home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / asm / utils / crossword / includes / cwdischandler.i < prev    next >
Encoding:
Text File  |  1980-01-04  |  59.9 KB  |  2,889 lines

  1.  
  2.  
  3. * Crossword disc functions file
  4. * This file contains all of the functions required to implement the
  5. * disc access panel.
  6.  
  7.  
  8. * DiscPanelOn(a6) -> d0
  9. * a6 = ptr to main program variables
  10. * Opens disc access panel windows & links them to a
  11. * common userport.
  12.  
  13. * Returns d0=NULL if failed to pop up the panel.
  14.  
  15. * d0/a0 corrupt
  16.  
  17.  
  18. DiscPanelOn    lea    DiscWindow1(pc),a0
  19.         move.l    ms_handle(a6),d0
  20.         move.l    d0,30(a0)    ;set Custom screen ptr
  21.  
  22.         CALLINT    OpenWindow
  23.  
  24.         move.l    d0,dp_window1(a6)
  25.         beq.s    DPON_Exit
  26.         move.l    d0,a0
  27.         move.l    RastPort(a0),dp_rastport1(a6)
  28.  
  29.         lea    DiscWindow2(pc),a0
  30.         move.l    ms_handle(a6),d0
  31.         move.l    d0,30(a0)
  32.  
  33.         CALLINT     OpenWindow
  34.  
  35.         move.l    d0,dp_window2(a6)
  36.         beq.s    DPON_Exit
  37.         move.l    d0,a0
  38.         move.l    RastPort(a0),dp_rastport2(a6)
  39.  
  40.         move.l    d0,a1        ;now copy the
  41.         move.l    dp_window1(a6),a0    ;Userport across
  42.  
  43.         move.l    UserPort(a0),d0
  44.         move.l    d0,dp_userport(a6)
  45.         move.l    d0,UserPort(a1)
  46.  
  47.         move.l    a1,a0
  48.         move.l    #GADGETUP+GADGETDOWN,d0
  49.         add.l    #DISKINSERTED+DISKREMOVED,d0
  50.         CALLINT    ModifyIDCMP
  51.  
  52.         moveq    #-1,d0        ;signal success
  53.  
  54. DPON_Exit    rts
  55.  
  56.  
  57. * DiscPanelOff(a6)
  58. * a6 = ptr to main program variables
  59. * Unlinks disc access panel windows from common userport,
  60. * then closes them.
  61.  
  62. * d0/a0 corrupt
  63.  
  64.  
  65. DiscPanelOff    move.l    dp_window2(a6),d0
  66.         beq.s    DPOFF_1
  67.  
  68.         move.l    d0,a0
  69.         clr.l    UserPort(a0)    ;here delink UserPort
  70.  
  71.         moveq    #0,d0
  72.         CALLINT    ModifyIDCMP
  73.  
  74.         move.l    dp_window2(a6),a0
  75.         CALLINT    CloseWindow
  76.  
  77. DPOFF_1        move.l    dp_window1(a6),d0
  78.         beq.s    DPOFF_2
  79.  
  80.         move.l    d0,a0
  81.         CALLINT    CloseWindow
  82.  
  83. DPOFF_2        rts
  84.  
  85.  
  86. * DoDiscPanel(a6)
  87. * a6 = ptr to main program variables
  88.  
  89. * Bring disc access panel to life, then enter event handler loop
  90. * for disc access panel until the "DONE!" gadget hit. Then, exit
  91. * the disc access panel.
  92.  
  93. * ASSUME ALL REGISTERS CORRUPT!
  94.  
  95.  
  96. DoDiscPanel    btst    #1,applic_flag2(a6)    ;requesting help?
  97.         beq.s    DDP_ok            ;no
  98.  
  99.         lea    Help_DA(pc),a0    ;get help panel
  100.         moveq    #6,d0        ;data
  101.  
  102.         bsr    _PopUpQR        ;pop up requester
  103.  
  104.         beq    ExitDP        ;and exit if NO gadget pressed
  105.  
  106. DDP_ok        bsr    DiscPanelOn
  107.  
  108.         beq.s    DoneDP
  109.  
  110.         bsr    CancelButtons    ;set initial buttons states
  111.  
  112.         bsr    DiscPointer
  113.  
  114.         bset    #5,applic_flag2(a6)    ;set Panel flag
  115.  
  116.         bsr    SetDF0        ;show contents of DF0:
  117.  
  118. DDP_1        move.l    dp_userport(a6),a0
  119.         lea    ehb_dp(pc),a5
  120.  
  121.         bsr    DoEvent        ;handle DP events
  122.  
  123.         btst    #5,applic_flag2(a6)    ;exiting panel?
  124.         bne.s    DDP_1            ;loop back if not
  125.  
  126.         move.l    dp_window2(a6),a0
  127.         CALLINT    ClearPointer
  128.  
  129.         move.l    dp_window1(a6),a0
  130.         CALLINT    ClearPointer
  131.  
  132. DoneDP        bsr    DiscPanelOff
  133.  
  134. ExitDP        rts
  135.  
  136.  
  137. * ByeDP(a6)
  138. * a6 = ptr to main program variables
  139. * Exit from Disc Access Panel
  140.  
  141. * nothing corrupt
  142.  
  143. ByeDP        bclr    #5,applic_flag2(a6)
  144.         rts
  145.  
  146.  
  147. * SortDir(a6) -> (a6)
  148. * a6 = ptr to main program variables
  149.  
  150. * generate sorted dir list.
  151. * Returns error code in vars list.
  152. * This edited version also checks to see if the
  153. * path supplied is a true directory. If it's a
  154. * file, then it exits and calls ForgetDir()
  155. * without further ado.
  156.  
  157. * d0-d7/a0-a2 corrupt
  158.  
  159.  
  160. SortDir        move.l    dir_name(a6),d1
  161.         move.l    #ACCESS_READ,d2
  162.  
  163.         CALLDOS    Lock        ;get dir lock
  164.         move.l    d0,dir_lock(a6)    ;got it?
  165.         bne.s    SDR_1        ;yes, continue
  166.  
  167.         moveq    #1,d0        ;else no lock available
  168.         bra    SDR_Error
  169.  
  170. SDR_1        move.l    #lh_sizeof,d0
  171.         move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  172.  
  173.         CALLEXEC    AllocMem
  174.         move.l    d0,dir_flist(a6)    ;got a list header?
  175.         bne.s    SDR_2
  176.  
  177.         moveq    #2,d0        ;else no memory available
  178.         bra    SDR_Error
  179.         
  180. SDR_2        move.l    #lh_sizeof,d0
  181.         move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  182.  
  183.         CALLEXEC    AllocMem
  184.         move.l    d0,dir_dlist(a6)    ;got a list header?
  185.         bne.s    SDR_3
  186.  
  187.         moveq    #2,d0        ;else no memory available
  188.         bra    SDR_Error
  189.  
  190. SDR_3        move.l    dir_flist(a6),a0    ;perform a NEWLIST
  191.         move.l    a0,(a0)        ;function on the list
  192.         addq.l    #4,(a0)        ;header struct
  193.         clr.l    4(a0)        ;for files list
  194.         move.l    a0,8(a0)
  195.         move.b    #1,12(a0)
  196.  
  197.         move.l    dir_dlist(a6),a0    ;perform a NEWLIST
  198.         move.l    a0,(a0)        ;function on the list
  199.         addq.l    #4,(a0)        ;header struct
  200.         clr.l    4(a0)        ;for dirs list
  201.         move.l    a0,8(a0)
  202.         move.b    #1,12(a0)
  203.  
  204.  
  205. * Ok, now we have the list structures. Now allocate some memory for
  206. * the FileInfoBlock.
  207.  
  208.  
  209.         move.l    #260,d0
  210.         move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  211.         CALLEXEC    AllocMem
  212.         move.l    d0,dir_iblk(a6)    ;got a FileInfoBlock?
  213.         bne.s    SDR_4        ;yes-continue
  214.  
  215.         moveq    #2,d0        ;else no memory availble
  216.         bra    SDR_Error
  217.  
  218.  
  219. * Now allocate some memory for the list nodes
  220.  
  221.  
  222. SDR_4        move.l    #4096,d0            ;4K should be enough
  223.         move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  224.         CALLEXEC    AllocMem
  225.         move.l    d0,dir_nodes(a6)        ;got node space?
  226.         bne.s    SDR_5            ;continue if so
  227.  
  228.         moveq    #2,d0
  229.         bra    SDR_Error
  230.  
  231.  
  232. * Now allocate some memory for the strings
  233.  
  234.  
  235. SDR_5        move.l    d0,dir_nodepos(a6)
  236.  
  237.         move.l    #16384,d0        ;16K should be enough
  238.         move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  239.         CALLEXEC    AllocMem
  240.         move.l    d0,dir_strings(a6)    ;got string space?
  241.         bne.s    SDR_6            ;continue if so
  242.  
  243.         moveq    #2,d0
  244.         bra    SDR_Error
  245.  
  246.  
  247. * Now start reading the directory!
  248.  
  249.  
  250. SDR_6        move.l    d0,dir_strpos(a6)
  251.  
  252.         moveq    #0,d0
  253.  
  254.         move.w    d0,dir_fcount(a6)    ;set up total file &
  255.         move.w    d0,dir_dcount(a6)    ;subdirectory counts
  256.  
  257.         move.l    dir_lock(a6),d1
  258.         move.l    dir_iblk(a6),d2
  259.  
  260.         CALLDOS    Examine        ;get dir name
  261.  
  262.         tst.l    d0
  263.         bne.s    SDR_6a        ;and continue if poss
  264.  
  265.         moveq    #3,d0        ;oops-non-accessible
  266.         bra    SDR_Error
  267.  
  268. SDR_6a        move.l    dir_iblk(a6),a0    ;check path
  269.         tst.l    4(a0)        ;is it a directory?
  270.         bpl.s    SDR_7        ;skip if so
  271.  
  272.         bsr    ForgetDir    ;else exit NOW
  273.         moveq    #4,d0        ;and signal the error
  274.         bra    SDR_Error
  275.  
  276. SDR_7        move.l    dir_lock(a6),d1
  277.         move.l    dir_iblk(a6),d2
  278.  
  279.         CALLDOS    ExNext        ;get entry
  280.  
  281.         tst.l    d0        ;run out of dir entries?
  282.         beq    SDR_8        ;skip if so
  283.  
  284.  
  285. * Here prepare for list update. Get d7=entry type (file/dir),
  286. * d6=ptr to list to use, d5=ptr to current string entry in
  287. * string space after the copy, d4=ptr to new node. Prior to
  288. * this, however, check for a .info file and if it is, don't
  289. * include it in the list.
  290.  
  291.  
  292.         move.l    dir_iblk(a6),a0    ;info block
  293.         lea    8(a0),a0        ;point to file/dir name string
  294.  
  295. SDR_15        tst.b    (a0)+        ;find EOS
  296.         bne.s    SDR_15
  297.  
  298.         subq.l    #1,a0        ;point to EOS
  299.         cmp.b    #"o",-(a0)    ;last char "o"?
  300.         bne.s    SDR_16        ;no
  301.         cmp.b    #"f",-(a0)    ;prev "f"?
  302.         bne.s    SDR_16        ;no
  303.         cmp.b    #"n",-(a0)    ;prev "n"?
  304.         bne.s    SDR_16        ;no
  305.         cmp.b    #"i",-(a0)    ;prev "i"?
  306.         bne.s    SDR_16        ;no
  307.         cmp.b    #".",-(a0)    ;prev "."?
  308.         beq.s    SDR_7        ;get another if so
  309.  
  310. SDR_16        move.l    dir_nodepos(a6),d4
  311.  
  312.         move.l    dir_iblk(a6),a0    ;get ptr to info block
  313.         move.l    4(a0),d7        ;get entry type
  314.         lea    8(a0),a0        ;point to string
  315.         move.l    dir_strpos(a6),d5
  316.         move.l    d5,a1
  317.         bsr    CopyString    ;copy to buffer
  318.         move.l    a1,dir_strpos(a6)    ;save new end of strings
  319.  
  320.         move.l    dir_flist(a6),d6    ;point to files list
  321.         tst.l    d7        ;entry = file?
  322.         bmi.s    SDR_9        ;skip if so
  323.         move.l    dir_dlist(a6),d6    ;else point to dirs list
  324.  
  325.  
  326. * Now check for empty list. If list empty, just append the
  327. * new node to the list.
  328.  
  329.  
  330. SDR_9        move.l    d6,a0
  331.         cmp.l    lh_TailPred(a0),a0    ;empty list?
  332.         bne.s    SDR_10            ;skip if not
  333.  
  334.  
  335. * Here, list empty. Create node, append to list.
  336.  
  337.  
  338.         move.l    d4,a0        ;ptr to new node
  339.         clr.b    ln_Type(a0)    ;create node
  340.         clr.b    ln_Pri(a0)
  341.         move.l    d5,ln_Name(a0)    ;pop in string
  342.  
  343.         move.l    d6,a0
  344.         move.l    d4,a1
  345.         sub.l    a2,a2
  346.  
  347. SDR_11        CALLEXEC    Insert        ;and pop it in
  348.  
  349.         tst.l    d7        ;file or dir?
  350.         smi    d0        ;set d0 if file
  351.         ext.w    d0
  352.         sub.w    d0,dir_fcount(a6)    ;update file count
  353.  
  354.         tst.l    d7        ;file or dir?
  355.         spl    d0        ;set d0 if dir
  356.         ext.w    d0
  357.         sub.w    d0,dir_dcount(a6)    ;update dir count
  358.  
  359.         move.l    d4,a0
  360.         add.w    #ln_sizeof,a0
  361.         move.l    a0,dir_nodepos(a6)    ;next new node!
  362.  
  363.         bra    SDR_7        ;and back for more
  364.  
  365.  
  366. * Here, list non-empty. Create node, compare strings
  367. * with previous nodes, until hit a higher string. If
  368. * hit end of list, put new node on end of list.
  369.  
  370.  
  371. SDR_10        move.l    d6,a2        ;ptr to list
  372.         move.l    lh_Head(a2),a2    ;ptr to 1st node
  373.  
  374. SDR_12        move.l    d5,a1        ;dest string
  375.         move.l    ln_Name(a2),a0    ;source string
  376.         bsr    CmpStr        ;compare strings
  377.         bcs.s    SDR_14        ;found a lower one-skip
  378.  
  379.         move.l    ln_Succ(a2),d0    ;point to next node
  380.         move.l    d6,a0        ;point to list
  381.         lea    lh_Tail(a0),a0
  382.         cmp.l    d0,a0        ;hit end of list?
  383.         beq.s    SDR_13        ;skip if hit end
  384.         move.l    d0,a2        ;else point to new node
  385.         bra.s    SDR_12        and resume scan
  386.  
  387.  
  388. * Here, we're ready to insert node. Create node & insert.
  389.  
  390.  
  391. SDR_14        move.l    ln_Pred(a2),a2    ;point to pred if str higher
  392.  
  393. SDR_13        move.l    d4,a0
  394.         clr.b    ln_Type(a0)    ;create node
  395.         clr.b    ln_Pri(a0)
  396.         move.l    d5,ln_Name(a0)    ;pop in string
  397.         move.l    d6,a0
  398.         move.l    d4,a1
  399.         bra.s    SDR_11
  400.  
  401.  
  402. * Here we've done it. Free the lock on the directory &
  403. * return with "all's well" error code.
  404.  
  405.  
  406. SDR_8        move.w    dir_dcount(a6),d0
  407.         add.w    dir_fcount(a6),d0
  408.         move.w    d0,dir_entnum(a6)    ;set total entry count
  409.  
  410.         moveq    #0,d0        ;signal all's well
  411.  
  412. SDR_Error    move.w    d0,dir_error(a6)
  413.  
  414.         move.l    dir_lock(a6),d1    ;got a lock?
  415.         beq.s    SDR_Done        ;skip if not
  416.         CALLDOS    UnLock        ;else Unlock it!
  417.  
  418. SDR_Done        rts
  419.  
  420.  
  421. * ForgetDir(a6)
  422. * a6 = ptr to main program variables
  423. * Deallocates all memory used by SortDir() &
  424. * thus forgets the sorted directory.
  425.  
  426. * d0/a1 corrupt
  427.  
  428.  
  429. ForgetDir    move.l    dir_strings(a6),d0
  430.         beq.s    FDR_4
  431.         move.l    d0,a1
  432.         move.l    #16384,d0
  433.         CALLEXEC    FreeMem
  434.  
  435. FDR_4        move.l    dir_nodes(a6),d0
  436.         beq.s    FDR_3
  437.         move.l    d0,a1
  438.         move.l    #4096,d0
  439.         CALLEXEC    FreeMem
  440.  
  441. FDR_3        move.l    dir_iblk(a6),d0
  442.         beq.s    FDR_2
  443.         move.l    d0,a1
  444.         move.l    #260,d0
  445.         CALLEXEC    FreeMem
  446.  
  447. FDR_2        move.l    dir_dlist(a6),d0
  448.         beq.s    FDR_1
  449.         move.l    d0,a1
  450.         move.l    #lh_sizeof,d0
  451.         CALLEXEC    FreeMem
  452.  
  453. FDR_1        move.l    dir_flist(a6),d0
  454.         beq.s    FDR_Done
  455.         move.l    d0,a1
  456.         move.l    #lh_sizeof,d0
  457.         CALLEXEC    FreeMem
  458.  
  459. FDR_Done        moveq    #0,d0            ;ensure that
  460.  
  461.         move.l    d0,dir_flist(a6)        ;all of these
  462.         move.l    d0,dir_dlist(a6)        ;variables do not
  463.         move.l    d0,dir_iblk(a6)        ;point to valid
  464.         move.l    d0,dir_nodes(a6)        ;memory areas!
  465.         move.l    d0,dir_nodepos(a6)
  466.         move.l    d0,dir_strings(a6)
  467.         move.l    d0,dir_strpos(a6)
  468.         move.w    d0,dir_fcount(a6)
  469.         move.w    d0,dir_dcount(a6)
  470.  
  471.         rts
  472.  
  473.  
  474. * SetPath1(a6)
  475. * a6 = ptr to main program variables
  476.  
  477. * Create path name from the volume & directory
  478. * gadgets. Called by code linked to Load/Save/Delete
  479. * gadgets.
  480.  
  481. * a0-a1 corrupt
  482.  
  483.  
  484. SetPath1        lea    ND_VolName(pc),a0        ;ptr to volume name
  485.         move.l    gg_SpecialInfo(a0),a0    ;gadget
  486.         move.l    si_Buffer(a0),a0        ;here point to string
  487.         tst.b    (a0)            ;null string?
  488.         beq.s    SP1_Done
  489.         move.l    dir_name(a6),a1
  490.         bsr    CopyString        ;copy to buffer
  491.  
  492.         subq.l    #1,a1            ;point to EOS
  493.  
  494.         lea    ND_DirName(pc),a0        ;ptr to directory name
  495.         move.l    gg_SpecialInfo(a0),a0    ;gadget
  496.         move.l    si_Buffer(a0),a0        ;here point to string
  497.         tst.b    (a0)            ;null string?
  498.         beq.s    SP1_Done
  499.         cmp.b    #"/",(a0)        ;initial "/"?
  500.         bne.s    SP1_B1            ;skip if not
  501.         addq.l    #1,a0            ;else point past it
  502.  
  503. SP1_B1        bsr    CopyString        ;copy to buffer
  504.  
  505.         subq.l    #1,a1            ;point to EOS
  506.  
  507. ;        lea    ND_FileName(pc),a0    ;ptr to file name
  508. ;        move.l    gg_SpecialInfo(a0),a0    ;gadget
  509. ;        move.l    si_Buffer(a0),a0        ;here point to string
  510. ;        tst.b    (a0)            ;null string?
  511. ;        beq.s    SP1_Done
  512.  
  513. ;        bsr    CopyString        ;copy to buffer
  514.  
  515. SP1_Done        rts
  516.  
  517.  
  518. * SetPath2(a6)
  519. * a6 = ptr to main program variables
  520.  
  521. * Create path name from the volume & directory
  522. * gadgets. Other code called from Rename gadget
  523. * calls this.
  524.  
  525. * a0-a1 corrupt
  526.  
  527.  
  528. SetPath2        lea    ND_VolName(pc),a0        ;ptr to volume name
  529.         move.l    gg_SpecialInfo(a0),a0    ;gadget
  530.         move.l    si_Buffer(a0),a0        ;here point to string
  531.         tst.b    (a0)            ;null string?
  532.         beq.s    SP2_Done
  533.         move.l    dir_rename(a6),a1
  534.         bsr    CopyString        ;copy to buffer
  535.  
  536.         subq.l    #1,a1            ;point to EOS
  537.  
  538.         lea    ND_DirName(pc),a0        ;ptr to directory name
  539.         move.l    gg_SpecialInfo(a0),a0    ;gadget
  540.         move.l    si_Buffer(a0),a0        ;here point to string
  541.         tst.b    (a0)            ;null string?
  542.         beq.s    SP2_Done
  543.         cmp.b    #"/",(a0)        ;initial "/"?
  544.         bne.s    SP2_B1            ;skip if not
  545.         addq.l    #1,a0            ;else point past it
  546.  
  547. SP2_B1        bsr    CopyString        ;copy to buffer
  548.  
  549.         subq.l    #1,a1            ;point to EOS
  550.  
  551. ;        lea    ND_NewName(pc),a0        ;ptr to rename name
  552. ;        move.l    gg_SpecialInfo(a0),a0    ;gadget
  553. ;        move.l    si_Buffer(a0),a0        ;here point to string
  554. ;        tst.b    (a0)            ;null string?
  555. ;        beq.s    SP2_Done
  556.  
  557. ;        bsr    CopyString        ;copy to buffer
  558.  
  559. SP2_Done        rts
  560.  
  561.  
  562. * SetDirTexts(a6)
  563. * a6 = ptr to main program variables
  564.  
  565. * Set the IntuiTexts for the directory list to point to
  566. * the directory strings, and then display them.
  567.  
  568. * d0-d5/a0-a2 corrupt
  569.  
  570.  
  571. SetDirTexts    tst.l    dir_dlist(a6)    ;list exists?
  572.         beq    SDTX_Done    ;exit NOW if not
  573.  
  574.         tst.l    dir_flist(a6)    ;list exists?
  575.         beq    SDTX_Done    ;exit NOW if not
  576.  
  577.         lea    ND_T1(pc),a0    ;point to ITexts
  578.  
  579.         moveq    #3,d3        ;colour byte
  580.  
  581.         moveq    #0,d0        ;no of texts processed
  582.  
  583.         move.w    dir_entpos(a6),d1    ;1st entry used
  584.         addq.w    #1,d1
  585.  
  586.  
  587. * First use dir_entpos(a6) to find nth entry in list (one we're
  588. * starting with). If we hit end of list before count hits zero,
  589. * change from dirs list to files list.
  590.  
  591.  
  592.         move.l    dir_dlist(a6),a1    ;ptr to list
  593.         move.l    a1,d4
  594.         lea    lh_Tail(a1),a2
  595.         move.l    a2,d5
  596.         move.l    lh_Head(a1),a1    ;point to 1st entry
  597.  
  598. SDTX_1        move.l    ln_Succ(a1),d2    ;got a successor?
  599.         beq.s    SDTX_2        ;no, so exit!
  600.  
  601.         subq.w    #1,d1        ;this entry?
  602.         beq.s    SDTX_4        ;skip if so
  603.  
  604.         move.l    d2,a1        ;else point to successor
  605.         bra.s    SDTX_1        ;and continue scan
  606.  
  607. SDTX_2        moveq    #1,d3        ;change colour!
  608.  
  609.         move.l    dir_flist(a6),a1
  610.         move.l    a1,d4
  611.         lea    lh_Tail(a1),a2
  612.         move.l    a2,d5
  613.         move.l    lh_Head(a1),a1
  614.  
  615. SDTX_3        move.l    ln_Succ(a1),d2    ;got a successor?
  616. ;        beq    SDTX_Done    ;no, so finished!
  617.         beq.s    SDTX_8
  618.  
  619.         subq.w    #1,d1        ;this entry?
  620.         beq.s    SDTX_4
  621.  
  622.         move.l    d2,a1        ;else point to successor
  623.         bra.s    SDTX_3        ;and continue scan
  624.  
  625.  
  626. * Here, we've found the first entry to use. Start inserting the
  627. * list texts into the IText structures.
  628.  
  629.  
  630. SDTX_4        move.l    ln_Name(a1),12(a0)    ;copy name ptr
  631.         move.b    d3,(a0)            ;set FGND colour
  632.         lea    20(a0),a2        ;point to next IText
  633.  
  634.         addq.w    #1,d0            ;this many done
  635.         cmp.w    #DIRCOUNT,d0        ;done them all?
  636.         beq.s    SDTX_5            ;exit if so
  637.  
  638.         move.l    a2,16(a0)        ;continue IText chain
  639.         move.l    a2,a0
  640.  
  641. SDTX_7        move.l    ln_Succ(a1),d2        ;get successor
  642.         cmp.l    d2,d5            ;hit list end?
  643.         beq.s    SDTX_6            ;skip if none
  644.  
  645.         move.l    d2,a1
  646.         bra.s    SDTX_4
  647.  
  648. SDTX_6        cmp.l    dir_dlist(a6),d4        ;end of dirs?
  649.         bne.s    SDTX_8            ;if not, leave loop
  650.  
  651.         move.l    dir_flist(a6),a1        ;else get files list
  652.         move.l    a1,d4
  653.         lea    lh_Tail(a1),a2
  654.         move.l    a2,d5
  655. ;        move.l    lh_Head(a1),a1
  656.  
  657.         moveq    #1,d3            ;and change colour
  658.         bra.s    SDTX_7            ;and continue
  659.  
  660.  
  661. * Here, we haven't enough text entries in either list. So fill in
  662. * the remaining entries with blanks.
  663.  
  664.  
  665. SDTX_8        lea    BlankDT(pc),a1    ;ptr to blank string
  666.  
  667. SDTX_9        move.l    a1,12(a0)    ;process IText
  668.         lea    20(a0),a2
  669.  
  670.         addq.w    #1,d0        ;update count
  671.         cmp.w    #DIRCOUNT,d0    ;done them all?
  672.         beq.s    SDTX_5
  673.  
  674.         move.l    a2,a0        ;point to next IText
  675.         bra.s    SDTX_9
  676.  
  677. SDTX_5        clr.l    16(a0)        ;end IText list chain        
  678.  
  679.         move.l    dp_rastport2(a6),a1
  680.         moveq    #4,d0
  681.         CALLGRAF    SetRast
  682.  
  683.         lea    ND_T1(pc),a1
  684.         moveq    #0,d0
  685.         move.l    d0,d1
  686.         move.l    dp_rastport2(a6),a0
  687.  
  688.         CALLINT    PrintIText
  689.  
  690. SDTX_Done    rts
  691.  
  692.  
  693. BlankDT        dc.b    "          ",0
  694.         even
  695.  
  696.  
  697. * SetDPProp(a6)
  698. * a6 = ptr to main program variables
  699.  
  700. * Take list entry counts formed by SortDir() & use to
  701. * create Disc Panel Propgadget values.
  702.  
  703. * d0-d5/a0-a2 corrupt
  704.  
  705.  
  706. SetDPProp    lea    ND_VPot(pc),a0
  707.         move.l    dp_window1(a6),a1
  708.         sub.l    a2,a2
  709.         moveq    #1,d5
  710.         move.w    #FREEVERT+PROPBORDERLESS,d0
  711.  
  712.         move.w    dir_entnum(a6),d2
  713.         cmp.w    #DIRCOUNT,d2    ;too few to scroll?
  714.         bhi.s    SDPP_1        ;skip if not
  715.  
  716.         moveq    #1,d4    ;else set PropGadget to
  717.         neg.w    d4    ;these values
  718.         moveq    #0,d2
  719.         move.l    d2,d1
  720.         move.l    d2,d3
  721.         bra.s    SDPP_2
  722.  
  723. SDPP_1        sub.w    #DIRCOUNT,d2    ;create no of scroll pos'ns
  724.         moveq    #1,d4
  725.         neg.w    d4
  726.         divu    d2,d4
  727.         moveq    #0,d2
  728.         move.l    d2,d1
  729.         move.l    d2,d3
  730.  
  731. SDPP_2        CALLINT    NewModifyProp
  732.  
  733.         clr.w    dir_entpos(a6)
  734.  
  735.         rts
  736.  
  737.  
  738. * DoDPProp(a6)
  739. * a6 = ptr to main program variables
  740. * handle the vertical PropGadget on the Disc Panel.
  741.  
  742. * d0-d2/a0/a5 corrupt
  743.  
  744.  
  745. DoDPProp        lea    ND_VPot(pc),a0
  746.         move.l    gg_SpecialInfo(a0),a0
  747.         move.l    a0,a5            ;get pot data
  748.  
  749. DDPP_1        moveq    #0,d0
  750.         move.l    d0,d1
  751.         move.w    pi_VertPot(a5),d0        ;get Pot and Body
  752.         move.w    pi_VertBody(a5),d1    ;values
  753.  
  754.         divu    d1,d0            ;get entpos value
  755.  
  756.         move.w    dir_entnum(a6),d2        ;get total slider size
  757.         sub.w    #DIRCOUNT,d2        ;data
  758.         bpl.s    DDPP_2
  759.  
  760.         moveq    #0,d2        ;use this if too small
  761.  
  762. DDPP_2        cmp.w    d2,d0        ;our value too big?
  763.         bcs.s    DDPP_3        ;skip if not
  764.  
  765.         move.w    d2,d0        ;else use this
  766.  
  767. DDPP_3        cmp.w    dir_entpos(a6),d0    ;already at this value?
  768.         beq.s    DDPP_4        ;skip if so
  769.  
  770.         move.w    d0,dir_entpos(a6)    ;else set new value
  771.  
  772.         bsr    SetDirTexts    ;and show new texts
  773.  
  774. DDPP_4        move.w    pi_Flags(a5),d0    ;playing with slider knob?
  775.         and.w    #KNOBHIT,d0
  776.         beq.s    DDPP_Done    ;exit if not
  777.  
  778.         btst    #6,$BFE001    ;else loop back until mouse
  779.         beq.s    DDPP_1        ;button released.
  780.  
  781. DDPP_Done    rts
  782.  
  783.  
  784. * IncDirPos(a6)
  785. * a6 = ptr to main program variables
  786.  
  787. * Scroll directory listing one entry down when the
  788. * Down gadget is pressed. Checks to see if scrolling
  789. * is possible first, & scolls only if so.
  790.  
  791. * d0-d5/a0-a2 corrupt
  792.  
  793.  
  794. IncDirPos    move.w    dir_entnum(a6),d0    ;check no. of dir entries
  795.         cmp.w    #DIRCOUNT,d0    ;enough entries?
  796.         bhi.s    IDPS_1        ;yes
  797. IDPS_2        rts            ;else skip
  798.  
  799. IDPS_1        move.w    dir_entpos(a6),d0    ;get position
  800.         addq.w    #1,d0        ;next position
  801.  
  802.         move.w    d0,d1        ;copy new position
  803.         add.w    #DIRCOUNT,d1
  804.         cmp.w    dir_entnum(a6),d1    ;overrun?
  805.         bhi.s    IDPS_2        ;exit if so
  806.         move.w    d0,dir_entpos(a6)    ;set new position
  807.  
  808.  
  809. * Now having updated the position, refresh the PropGadget. First
  810. * get its data, then move slider, then refresh the gadget.
  811.  
  812.  
  813.         lea    ND_VPot(pc),a0        ;ptr to PropGadget
  814.         move.l    gg_SpecialInfo(a0),a1    ;get SpecialInfo
  815.  
  816.         move.w    pi_Flags(a1),d0
  817.         move.w    pi_HorizPot(a1),d1
  818.         move.w    pi_VertPot(a1),d2
  819.         move.w    pi_HorizBody(a1),d3
  820.         move.w    pi_VertBody(a1),d4
  821.  
  822.         moveq    #1,d5
  823.  
  824.         add.w    d4,d2
  825.  
  826.         move.l    dp_window1(a6),a1
  827.         sub.l    a2,a2
  828.  
  829.         CALLINT    NewModifyProp
  830.  
  831.  
  832. * Now redisplay the texts.
  833.  
  834.  
  835.         bsr    SetDirTexts
  836.  
  837.         rts
  838.  
  839.  
  840. * DecDirPos(a6)
  841. * a6 = ptr to main program variables
  842.  
  843. * Scroll directory listing one entry up when the
  844. * Up gadget is pressed. Checks to see if scrolling
  845. * is possible first, & scolls only if so.
  846.  
  847. * d0-d5/a0-a2 corrupt
  848.  
  849.  
  850. DecDirPos    move.w    dir_entnum(a6),d0    ;check no. of dir entries
  851.         cmp.w    #DIRCOUNT,d0    ;enough entries?
  852.         bhi.s    DDPS_1        ;yes
  853. DDPS_2        rts            ;else skip
  854.  
  855. DDPS_1        move.w    dir_entpos(a6),d0    ;get position
  856.         beq.s    DDPS_2        ;if at top, exit
  857.         subq.w    #1,d0        ;next position
  858.  
  859.         move.w    d0,dir_entpos(a6)    ;set new position
  860.  
  861.  
  862. * Now having updated the position, refresh the PropGadget. First
  863. * get its data, then move slider, then refresh the gadget.
  864.  
  865.  
  866.         lea    ND_VPot(pc),a0        ;ptr to PropGadget
  867.         move.l    gg_SpecialInfo(a0),a1    ;get SpecialInfo
  868.  
  869.         move.w    pi_Flags(a1),d0
  870.         move.w    pi_HorizPot(a1),d1
  871.         move.w    pi_VertPot(a1),d2
  872.         move.w    pi_HorizBody(a1),d3
  873.         move.w    pi_VertBody(a1),d4
  874.  
  875.         moveq    #1,d5
  876.  
  877.         sub.w    d4,d2
  878.  
  879.         move.l    dp_window1(a6),a1
  880.         sub.l    a2,a2
  881.  
  882.         CALLINT    NewModifyProp
  883.  
  884.  
  885. * Now redisplay the texts.
  886.  
  887.  
  888.         bsr    SetDirTexts
  889.  
  890.         rts
  891.  
  892.  
  893. * GetParent(a6)
  894. * a6 = ptr to main program variables
  895. * if directory name gadget contains a directory
  896. * name, find the parent directory and display the
  897. * contents using SetDirTexts(). If no directory
  898. * name, we're at the root, so exit.
  899.  
  900. * corrupt
  901.  
  902.  
  903. GetParent    lea    ND_DirName(pc),a1        ;ptr to gadget
  904.         move.l    a1,-(sp)            ;save it
  905.         move.l    dp_window1(a6),a0
  906.         moveq    #1,d0
  907.  
  908.         CALLINT    RemoveGList        ;unlink it
  909.  
  910.         move.l    (sp)+,a0            ;recover it
  911.  
  912.         move.l    gg_SpecialInfo(a0),a0    ;ptr to SpecialInfo
  913.         move.l    si_Buffer(a0),a0        ;ptr to dir name
  914.  
  915.         tst.b    (a0)            ;at root dir?
  916.         beq.s    GPT_Done            ;exit if so
  917.  
  918. GPT_1        tst.b    (a0)+        ;skip to end of text
  919.         bne.s    GPT_1
  920.  
  921.         subq.l    #1,a0        ;point to EOS
  922.  
  923. GPT_2        cmp.b    #"/",-(a0)    ;found directory separator?
  924.         bne.s    GPT_2
  925.  
  926.         clr.b    (a0)        ;EOS it out!
  927.  
  928.         lea    ND_DirName(pc),a1
  929.         move.l    dp_window1(a6),a0
  930.         sub.l    a2,a2
  931.         moveq    #15,d0
  932.         moveq    #1,d1
  933.  
  934.         CALLINT    AddGList        ;link gadget back in
  935.  
  936.         lea    ND_DirName(pc),a0
  937.         move.l    dp_window1(a6),a1
  938.         sub.l    a2,a2
  939.         moveq    #1,d0
  940.  
  941.         CALLINT    RefreshGList    ;and show results
  942.  
  943.         bra    ShowDir        ;now show directory!
  944.  
  945. GPT_Done        rts
  946.  
  947.  
  948. * SetDF0(a6)
  949. * a6 = ptr to main program variables
  950.  
  951. * Sets the "Volume" string gadget to "DF0:"
  952. * and activates the SortDir() routine. Also
  953. * clears the texts from the DirName and the
  954. * FileName gadgets.
  955.  
  956.  
  957. * d0-d1/a0-a2 corrupt
  958.  
  959.  
  960. SetDF0        lea    ND_VolName(pc),a1        ;unlink the string
  961.         move.l    dp_window1(a6),a0        ;gadgets prior to
  962.         moveq    #3,d0            ;alteration
  963.  
  964.         CALLINT    RemoveGList
  965.  
  966.         lea    ND_VolName(pc),a0        ;gadget ptr
  967.         move.l    a0,a1            ;keep a copy
  968.  
  969.         move.l    gg_SpecialInfo(a0),a0    ;Now pop in the
  970.         move.w    #4,si_BufferPos(a0)    ;text for the
  971.         move.l    si_Buffer(a0),a0        ;drive DF0:
  972.         move.l    #"DF0:",(a0)+        ;in the volume name
  973.         clr.b    (a0)            ;gadget
  974.  
  975.         move.l    a1,a0            ;recover copy
  976.  
  977.         move.l    (a1),a1        ;next gadget (=dir name)
  978.  
  979.         move.l    gg_SpecialInfo(a1),a2    ;now clear the
  980.         clr.w    si_BufferPos(a2)        ;directory name
  981.         move.l    si_Buffer(a2),a2        ;gadget
  982.         clr.b    (a2)
  983.  
  984. ;        move.l    (a1),a1        ;next gadget (=file name)
  985.  
  986. ;        move.l    gg_SpecialInfo(a1),a2    ;now clear the
  987. ;        clr.w    si_BufferPos(a2)        ;file name
  988. ;        move.l    si_Buffer(a2),a2        ;gadget
  989. ;        clr.b    (a2)
  990.  
  991.         move.l    a0,a1            ;these gadgets are
  992.         move.l    dp_window1(a6),a0        ;in a window, not a
  993.         sub.l    a2,a2            ;requester
  994.  
  995.         moveq    #14,d0            ;now link them
  996.         moveq    #3,d1            ;back in
  997.  
  998.         CALLINT    AddGList
  999.  
  1000.         lea    ND_VolName(pc),a0        ;now refresh the
  1001.         move.l    dp_window1(a6),a1        ;gadget
  1002.         sub.l    a2,a2
  1003.         moveq    #3,d0
  1004.  
  1005.         CALLINT    RefreshGList
  1006.  
  1007. ShowDir        bsr    ForgetDir
  1008.  
  1009.         lea    AcrossBuf(pc),a0
  1010.         move.l    a0,dir_name(a6)
  1011.  
  1012.         bsr    SetPath1
  1013.         bsr    SortDir
  1014.         bsr    SetDPProp
  1015.  
  1016.         bsr    SetDirTexts
  1017.  
  1018.         rts
  1019.  
  1020.  
  1021. * SetDF1(a6)
  1022. * a6 = ptr to main program variables
  1023.  
  1024. * Sets the "Volume" string gadget to "DF1:"
  1025. * and activates the SortDir() routine.
  1026.  
  1027.  
  1028. * d0-d1/a0-a2 corrupt
  1029.  
  1030.  
  1031. SetDF1        lea    ND_VolName(pc),a1        ;unlink the string
  1032.         move.l    dp_window1(a6),a0        ;gadgets prior to
  1033.         moveq    #3,d0            ;alteration
  1034.  
  1035.         CALLINT    RemoveGList
  1036.  
  1037.         lea    ND_VolName(pc),a0        ;gadget ptr
  1038.         move.l    a0,a1            ;keep a copy
  1039.  
  1040.         move.l    gg_SpecialInfo(a0),a0    ;Now pop in the
  1041.         move.w    #4,si_BufferPos(a0)    ;text for the
  1042.         move.l    si_Buffer(a0),a0        ;drive DF1:
  1043.         move.l    #"DF1:",(a0)+        ;in the volume name
  1044.         clr.b    (a0)            ;gadget
  1045.  
  1046.         move.l    a1,a0            ;recover copy
  1047.  
  1048.         move.l    (a1),a1        ;next gadget (=dir name)
  1049.  
  1050.         move.l    gg_SpecialInfo(a1),a2    ;now clear the
  1051.         clr.w    si_BufferPos(a2)        ;directory name
  1052.         move.l    si_Buffer(a2),a2        ;gadget
  1053.         clr.b    (a2)
  1054.  
  1055. ;        move.l    (a1),a1        ;next gadget (=file name)
  1056.  
  1057. ;        move.l    gg_SpecialInfo(a1),a2    ;now clear the
  1058. ;        clr.w    si_BufferPos(a2)        ;file name
  1059. ;        move.l    si_Buffer(a2),a2        ;gadget
  1060. ;        clr.b    (a2)
  1061.  
  1062.         move.l    a0,a1            ;these gadgets are
  1063.         move.l    dp_window1(a6),a0        ;in a window, not a
  1064.         sub.l    a2,a2            ;requester
  1065.  
  1066.         moveq    #14,d0            ;now link them
  1067.         moveq    #3,d1            ;back in
  1068.  
  1069.         CALLINT    AddGList
  1070.  
  1071.         lea    ND_VolName(pc),a0        ;now refresh the
  1072.         move.l    dp_window1(a6),a1        ;gadget
  1073.         sub.l    a2,a2
  1074.         moveq    #3,d0
  1075.  
  1076.         CALLINT    RefreshGList
  1077.  
  1078.         bra    ShowDir
  1079.  
  1080.  
  1081. * SetRAM(a6)
  1082. * a6 = ptr to main program variables
  1083.  
  1084. * Sets the "Volume" string gadget to "RAM:"
  1085. * and activates the SortDir() routine.
  1086.  
  1087.  
  1088. * d0-d1/a0-a2 corrupt
  1089.  
  1090.  
  1091. SetRAM        lea    ND_VolName(pc),a1        ;unlink the string
  1092.         move.l    dp_window1(a6),a0        ;gadgets prior to
  1093.         moveq    #3,d0            ;alteration
  1094.  
  1095.         CALLINT    RemoveGList
  1096.  
  1097.         lea    ND_VolName(pc),a0        ;gadget ptr
  1098.         move.l    a0,a1            ;keep a copy
  1099.  
  1100.         move.l    gg_SpecialInfo(a0),a0    ;Now pop in the
  1101.         move.w    #4,si_BufferPos(a0)    ;text for the
  1102.         move.l    si_Buffer(a0),a0        ;drive DF1:
  1103.         move.l    #"RAM:",(a0)+        ;in the volume name
  1104.         clr.b    (a0)            ;gadget
  1105.  
  1106.         move.l    a1,a0            ;recover copy
  1107.  
  1108.         move.l    (a1),a1        ;next gadget (=dir name)
  1109.  
  1110.         move.l    gg_SpecialInfo(a1),a2    ;now clear the
  1111.         clr.w    si_BufferPos(a2)        ;directory name
  1112.         move.l    si_Buffer(a2),a2        ;gadget
  1113.         clr.b    (a2)
  1114.  
  1115. ;        move.l    (a1),a1        ;next gadget (=file name)
  1116.  
  1117. ;        move.l    gg_SpecialInfo(a1),a2    ;now clear the
  1118. ;        clr.w    si_BufferPos(a2)        ;file name
  1119. ;        move.l    si_Buffer(a2),a2        ;gadget
  1120. ;        clr.b    (a2)
  1121.  
  1122.         move.l    a0,a1            ;these gadgets are
  1123.         move.l    dp_window1(a6),a0        ;in a window, not a
  1124.         sub.l    a2,a2            ;requester
  1125.  
  1126.         moveq    #14,d0            ;now link them
  1127.         moveq    #3,d1            ;back in
  1128.  
  1129.         CALLINT    AddGList
  1130.  
  1131.         lea    ND_VolName(pc),a0        ;now refresh the
  1132.         move.l    dp_window1(a6),a1        ;gadget
  1133.         sub.l    a2,a2
  1134.         moveq    #3,d0
  1135.  
  1136.         CALLINT    RefreshGList
  1137.  
  1138.         bra    ShowDir
  1139.  
  1140.  
  1141. * SetHardDisc(a6)
  1142. * a6 = ptr to main program variables
  1143.  
  1144. * Sets the "Volume" string gadget to "DH:"
  1145. * and activates the SortDir() routine.
  1146.  
  1147.  
  1148. * d0-d1/a0-a2 corrupt
  1149.  
  1150.  
  1151. SetHardDisc    lea    ND_VolName(pc),a1        ;unlink the string
  1152.         move.l    dp_window1(a6),a0        ;gadgets prior to
  1153.         moveq    #3,d0            ;alteration
  1154.  
  1155.         CALLINT    RemoveGList
  1156.  
  1157.         lea    ND_VolName(pc),a0        ;gadget ptr
  1158.         move.l    a0,a1            ;keep a copy
  1159.  
  1160.         move.l    gg_SpecialInfo(a0),a0    ;Now pop in the
  1161.         move.w    #4,si_BufferPos(a0)    ;text for the
  1162.         move.l    si_Buffer(a0),a0        ;drive DF1:
  1163.         move.l    #"DH:",(a0)+        ;in the volume name
  1164.         clr.b    (a0)            ;gadget
  1165.  
  1166.         move.l    a1,a0            ;recover copy
  1167.  
  1168.         move.l    (a1),a1        ;next gadget (=dir name)
  1169.  
  1170.         move.l    gg_SpecialInfo(a1),a2    ;now clear the
  1171.         clr.w    si_BufferPos(a2)        ;directory name
  1172.         move.l    si_Buffer(a2),a2        ;gadget
  1173.         clr.b    (a2)
  1174.  
  1175. ;        move.l    (a1),a1        ;next gadget (=file name)
  1176.  
  1177. ;        move.l    gg_SpecialInfo(a1),a2    ;now clear the
  1178. ;        clr.w    si_BufferPos(a2)        ;file name
  1179. ;        move.l    si_Buffer(a2),a2        ;gadget
  1180. ;        clr.b    (a2)
  1181.  
  1182.         move.l    a0,a1            ;these gadgets are
  1183.         move.l    dp_window1(a6),a0        ;in a window, not a
  1184.         sub.l    a2,a2            ;requester
  1185.  
  1186.         moveq    #14,d0            ;now link them
  1187.         moveq    #3,d1            ;back in
  1188.  
  1189.         CALLINT    AddGList
  1190.  
  1191.         lea    ND_VolName(pc),a0        ;now refresh the
  1192.         move.l    dp_window1(a6),a1        ;gadget
  1193.         sub.l    a2,a2
  1194.         moveq    #3,d0
  1195.  
  1196.         CALLINT    RefreshGList
  1197.  
  1198.         bra    ShowDir
  1199.  
  1200.  
  1201. * CmpStr(a0,a1) -> CCR
  1202. * a0=ptr to SOURCE string
  1203. * a1=ptr to DESTINATION string
  1204.  
  1205. * Uses 68000 CMP instruction convention, namely
  1206. * CMP source,destination
  1207.  
  1208. * Returns Z set if strings equal, else C set if
  1209. * dest<source
  1210.  
  1211. * Assumes normal ASCII character set, and ignores
  1212. * letter case.
  1213.  
  1214. * d0-d1 corrupt
  1215.  
  1216.  
  1217. CmpStr        move.b    (a0)+,d0        ;get source char
  1218.         move.b    (a1)+,d1        ;get dest char
  1219.  
  1220.         cmp.b    #"a",d0        ;lower case letter?
  1221.         bcs.s    CPS_1        ;no
  1222.         cmp.b    #"z",d0
  1223.         bhi.s    CPS_1
  1224.         and.b    #$DF,d0        ;make upper case if so
  1225.  
  1226. CPS_1        cmp.b    #"a",d1        ;lower case letter?
  1227.         bcs.s    CPS_2        ;no
  1228.         cmp.b    #"z",d1
  1229.         bhi.s    CPS_2
  1230.         and.b    #$DF,d1        ;make upper case if so
  1231.  
  1232. CPS_2        cmp.b    d0,d1        ;chars equal?
  1233.         bne.s    CPS_3
  1234.         tst.b    d0        ;EOS met?
  1235.         bne.s    CmpStr        ;back if not
  1236.  
  1237. CPS_3        rts            ;done!
  1238.  
  1239.  
  1240. * CopyString(a0,a1)
  1241. * a0 = ptr to string to copy
  1242. * a1 = ptr to where to copy it to
  1243. * copies ASCIIZ string
  1244.  
  1245. * a0/a1 corrupt
  1246.  
  1247.  
  1248. CopyString    move.b    (a0)+,(a1)+
  1249.         bne.s    CopyString
  1250.  
  1251.         rts
  1252.  
  1253.  
  1254. * Routines for text selection using the gadgets linked to the
  1255. * text listing window of the disc access panel.
  1256.  
  1257. * The following routines set D0 equal to the 'gadget number'
  1258. * for the given gadget (NOT equal to gg_GadgetID!) and then
  1259. * drops through to PickTextItem() below.
  1260.  
  1261.  
  1262. EntPick1        moveq    #0,d0
  1263.         bra.s    PickTextItem
  1264.  
  1265. EntPick2        moveq    #1,d0
  1266.         bra.s    PickTextItem
  1267.  
  1268. EntPick3        moveq    #2,d0
  1269.         bra.s    PickTextItem
  1270.  
  1271. EntPick4        moveq    #3,d0
  1272.         bra.s    PickTextItem
  1273.  
  1274. EntPick5        moveq    #4,d0
  1275.         bra.s    PickTextItem
  1276.  
  1277. EntPick6        moveq    #5,d0
  1278.         bra.s    PickTextItem
  1279.  
  1280. EntPick7        moveq    #6,d0
  1281.         bra.s    PickTextItem
  1282.  
  1283. EntPick8        moveq    #7,d0
  1284.         bra.s    PickTextItem
  1285.  
  1286. EntPick9        moveq    #8,d0
  1287.  
  1288.  
  1289. * PickTextItem(a6,d0)
  1290. * a6 = ptr to main program variables
  1291. * d0 = gadget number (from 0 to 8-supplied by
  1292. * the calling gadget)
  1293.  
  1294. * Note:because IText structs have different colours for
  1295. * file and dir text items, this is used to differentiate
  1296. * them. Far easier than re-scanning the lists.
  1297.  
  1298. * d0-d2/a0-a2 corrupt
  1299.  
  1300.  
  1301. PickTextItem    mulu    #20,d0        ;20 = size of IText struct!
  1302.         add.l    #ND_T1,d0    ;create pointer
  1303.         move.l    d0,a0
  1304.  
  1305.         move.b    (a0),d0        ;get colour
  1306.         cmp.b    #1,d0        ;white? (i.e., file)
  1307.         beq.s    PTI_1        ;skip if so
  1308.  
  1309.  
  1310. * Here we simply assume that it's a directory. Get text ptr
  1311. * and link into the dir string gadget.
  1312.  
  1313.  
  1314.         move.l    12(a0),a0
  1315.         move.l    a0,-(sp)        ;get ptr to string & save
  1316.         lea    BlankDT(pc),a1
  1317.         bsr    CmpStr        ;blank string?
  1318.         beq.s    PTI_Nogo        ;skip if so
  1319.  
  1320.         lea    ND_DirName(pc),a1
  1321.         move.l    dp_window1(a6),a0
  1322.         moveq    #1,d0
  1323.  
  1324.         CALLINT    RemoveGList
  1325.  
  1326.         lea    ND_DirName(pc),a1
  1327.         move.l    gg_SpecialInfo(a1),a1
  1328.         move.l    si_Buffer(a1),a1        ;point to buffer
  1329.  
  1330. PTI_2        tst.b    (a1)+        ;skip to EOS
  1331.         bne.s    PTI_2
  1332.         subq.l    #1,a1        ;point to EOS proper
  1333.  
  1334.         move.l    (sp)+,a0
  1335.  
  1336.         move.b    #"/",(a1)+    ;put in dir separator
  1337.         bsr    CopyString    ;and extend path
  1338.  
  1339.         lea    ND_DirName(pc),a1
  1340.         move.l    dp_window1(a6),a0
  1341.         sub.l    a2,a2
  1342.         moveq    #15,d0    ;position in list
  1343.         moveq    #1,d1
  1344.  
  1345.         CALLINT    AddGList
  1346.  
  1347.         lea    ND_DirName(pc),a0
  1348.         move.l    dp_window1(a6),a1
  1349.         sub.l    a2,a2
  1350.         moveq    #1,d0
  1351.  
  1352.         CALLINT    RefreshGList
  1353.  
  1354.         bra    ShowDir
  1355.  
  1356.  
  1357. * Here, we've clicked upon a blank string, so tidy the stack & kiss
  1358. * this routine goodbye.
  1359.  
  1360.  
  1361. PTI_Nogo        tst.l    (sp)+
  1362.         rts
  1363.  
  1364.  
  1365. * Here it's a file name. Pop it into the file name gadget
  1366. * but DON'T show the new directory. Keep the directory
  1367. * listing as is so that it can still be scrolled to find
  1368. * new choices. Signal that a valid filename exists.
  1369.  
  1370.  
  1371. PTI_1        move.l    12(a0),a0
  1372.         move.l    a0,-(sp)        ;get ptr to string & save
  1373.         lea    BlankDT(pc),a1
  1374.         bsr    CmpStr        ;blank string?
  1375.         beq.s    PTI_Nogo        ;skip if so
  1376.  
  1377.         lea    ND_FileName(pc),a1
  1378.         move.l    dp_window1(a6),a0
  1379.         moveq    #1,d0
  1380.  
  1381.         CALLINT    RemoveGList
  1382.  
  1383.         lea    ND_FileName(pc),a1
  1384.         move.l    gg_SpecialInfo(a1),a1
  1385.         move.l    si_Buffer(a1),a1        ;point to buffer
  1386.  
  1387.         move.l    (sp)+,a0
  1388.  
  1389.         bsr    CopyString    ;and extend path
  1390.  
  1391.         lea    ND_FileName(pc),a1
  1392.         move.l    dp_window1(a6),a0
  1393.         sub.l    a2,a2
  1394.         moveq    #16,d0    ;position in list
  1395.         moveq    #1,d1
  1396.  
  1397.         CALLINT    AddGList
  1398.  
  1399.         lea    ND_FileName(pc),a0
  1400.         move.l    dp_window1(a6),a1
  1401.         sub.l    a2,a2
  1402.         moveq    #1,d0
  1403.  
  1404.         CALLINT    RefreshGList
  1405.  
  1406.  
  1407. * No RTS here, so that routine can fall through to CheckFileName()
  1408. * below.
  1409.  
  1410.  
  1411.  
  1412. * CheckFileName(a6)
  1413. * a6 = ptr to main program variables
  1414.  
  1415. * Tests contents of file name gadget to see if a
  1416. * filename exists. Not a sophisticated check, but
  1417. * if should be enough. Also called by hitting RETURN
  1418. * within filename gadget.
  1419.  
  1420. * a0 corrupt
  1421.  
  1422.  
  1423. CheckFileName    bclr    #7,file_flag2(a6)        ;invalid filename for now
  1424.  
  1425.         lea    ND_FileName(pc),a0    ;ptr to gadget
  1426.         move.l    gg_SpecialInfo(a0),a0    ;ptr to si_
  1427.         move.l    si_Buffer(a0),a0        ;ptr to string
  1428.  
  1429.         tst.b    (a0)            ;any text?
  1430.         beq.s    CFN_Done            ;skip if so
  1431.  
  1432.         bset    #7,file_flag2(a6)        ;signal valid filename
  1433.  
  1434. CFN_Done        rts
  1435.  
  1436.  
  1437. * CheckReName(a6)
  1438. * a6 = ptr to main program variables
  1439.  
  1440. * Tests contents of rename gadget to see if a
  1441. * filename exists. Not a sophisticated check, but
  1442. * if should be enough. Also called by hitting RETURN
  1443. * within rename gadget.
  1444.  
  1445. * a0 corrupt
  1446.  
  1447.  
  1448. CheckReName    bclr    #6,file_flag2(a6)        ;invalid rename for now
  1449.  
  1450.         lea    ND_NewName(pc),a0        ;ptr to gadget
  1451.         move.l    gg_SpecialInfo(a0),a0    ;ptr to si_
  1452.         move.l    si_Buffer(a0),a0        ;ptr to string
  1453.  
  1454.         tst.b    (a0)            ;any text?
  1455.         beq.s    CRN_Done            ;skip if so
  1456.  
  1457.         bset    #6,file_flag2(a6)        ;signal valid rename
  1458.  
  1459. CRN_Done        rts
  1460.  
  1461.  
  1462. * SaveFile(a6)
  1463. * a6 = ptr to main program variables
  1464.  
  1465. * Saves crossword program file. Uses IFF Format!
  1466.  
  1467. * ASSUME ALL REGISTERS CORRUPT
  1468.  
  1469. * Note:Bug now removed. Previously, if clue list existed but
  1470. * text pointers were NULL, then the computation for the IFF
  1471. * chunk size was erroneous - added extra 2 bytes per NULL-
  1472. * pointer entry. However, when saving, this value was written
  1473. * yet the extra 2 bytes per entry weren't. So the FindChunk()
  1474. * routine was thrown off track. This has now been corrected
  1475. * by changing addq.l #2,d0 to addq.l #1,d0 for reserving a
  1476. * word-aligned NULL for a null text entry. Now the word-aligning
  1477. * code won't add on the extra 2 bytes.
  1478.  
  1479.  
  1480. SaveFile        moveq    #0,d0
  1481.         move.l    d0,file_size(a6)
  1482.         move.l    d0,file_buffer(a6)
  1483.         move.l    d0,file_acs(a6)
  1484.         move.l    d0,file_dns(a6)
  1485.         st    wantdir(a6)
  1486.         moveq    #0,d3
  1487.  
  1488.  
  1489. * Find size of proposed ACCL chunk. If it ends up zero, we
  1490. * don't write one.
  1491.  
  1492.  
  1493.         move.l    clue_list(a6),a0    ;ptr to list header
  1494.         move.l    clh_AcList(a0),d0    ;Across list exists?
  1495.         beq.s    Save_F1        ;skip if not
  1496.  
  1497.         addq.l    #8,d3
  1498.         move.w    clh_AcCount(a0),d1    ;no of entries
  1499.         move.l    d0,a0            ;ptr to Across list
  1500.         moveq    #0,d0            ;total byte count
  1501.  
  1502. Save_F2        move.l    cle_Text(a0),d2    ;text ptr exists?
  1503.         beq.s    Save_F3_1    ;skip if not
  1504.  
  1505.         move.l    d2,a1        ;copy text ptr
  1506.  
  1507. Save_F5        tst.b    (a1)        ;hit EOS?
  1508.         beq.s    Save_F3        ;skip if so
  1509.         addq.l    #1,d0        ;else +1 char count
  1510.         addq.l    #1,a1        ;and point to next char
  1511.         bra.s    Save_F5
  1512.  
  1513. Save_F3_1    addq.l    #1,d0        ;reserve space for NULLs
  1514.  
  1515. ;        addq.l    #2,d0        ;reserve space for NULLs
  1516.  
  1517. Save_F3        addq.l    #8,d0        ;add on extra data size
  1518.         addq.l    #1,d0        ;and EOS byte
  1519.         btst    #0,d0        ;not aligned?
  1520.         beq.s    Save_F4        ;skip if word aligned
  1521.         addq.l    #1,d0        ;else word align
  1522.  
  1523. Save_F4        add.w    #cle_sizeof,a0    ;next entry
  1524.         subq.w    #1,d1        ;done them all?
  1525.         bne.s    Save_F2        ;loop back if not
  1526.  
  1527.         move.l    d0,file_acs(a6)    ;this is ACCL chunk size
  1528.  
  1529.  
  1530. Save_F1        move.l    clue_list(a6),a0    ;ptr to list header
  1531.         move.l    clh_DnList(a0),d0    ;Down list exists?
  1532.         beq.s    Save_F6        ;skip if not
  1533.  
  1534.         addq.l    #8,d3
  1535.         move.w    clh_DnCount(a0),d1    ;no of entries
  1536.         move.l    d0,a0            ;ptr to Down list
  1537.         moveq    #0,d0            ;total byte count
  1538.  
  1539. Save_F7        move.l    cle_Text(a0),d2    ;text ptr exists?
  1540.         beq.s    Save_F8_1    ;skip if not
  1541.  
  1542.         move.l    d2,a1        ;copy text ptr
  1543.  
  1544. Save_F10        tst.b    (a1)        ;hit EOS?
  1545.         beq.s    Save_F8        ;skip if so
  1546.         addq.l    #1,d0        ;else +1 char count
  1547.         addq.l    #1,a1        ;and point to next char
  1548.         bra.s    Save_F10
  1549.  
  1550. Save_F8_1    addq.l    #1,d0        ;reserve space for NULLs
  1551.  
  1552. ;        addq.l    #2,d0        ;reserve space for NULLs
  1553.  
  1554. Save_F8        addq.l    #8,d0        ;add on extra data size
  1555.         addq.l    #1,d0        ;and EOS byte
  1556.         btst    #0,d0        ;not aligned?
  1557.         beq.s    Save_F9        ;skip if word aligned
  1558.         addq.l    #1,d0        ;else word align
  1559.  
  1560. Save_F9        add.w    #cle_sizeof,a0    ;next entry
  1561.         subq.w    #1,d1        ;done them all?
  1562.         bne.s    Save_F7        ;loop back if not
  1563.  
  1564.         move.l    d0,file_dns(a6)    ;this is DNCL chunk size
  1565.  
  1566.  
  1567. * Now compute entire file size.
  1568.  
  1569.  
  1570. Save_F6        add.l    file_acs(a6),d0    ;total size of 2 chunks
  1571.  
  1572.         add.l    grid_bytes(a6),d0
  1573.  
  1574.         add.l    #50,d0
  1575.         add.l    d3,d0        ;this is file size!
  1576.  
  1577.         move.l    d0,file_size(a6)    ;save it
  1578.  
  1579.  
  1580. * Now try to allocate memory for IFF file
  1581.  
  1582.  
  1583.         move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  1584.         CALLEXEC    AllocMem
  1585.         move.l    d0,file_buffer(a6)    ;can we do it?
  1586.         bne.s    Save_F6a            ;skip if so
  1587.  
  1588.         moveq    #-1,d0        ;otherwise
  1589.         bra    Load_Error    ;report the error
  1590.  
  1591. ;        beq    Save_F11            ;skip if not
  1592.  
  1593.  
  1594. * Now write the file out as an IFF file to the buffer.
  1595.  
  1596.  
  1597. Save_F6a        move.l    d0,a0        ;ptr to buffer
  1598.  
  1599.         move.l    #"FORM",(a0)+    ;write out FORM
  1600.         move.l    file_size(a6),d0
  1601.         subq.l    #8,d0
  1602.         move.l    d0,(a0)+        ;form size
  1603.         move.l    #"CRWD",(a0)+    ;form type = CRWD
  1604.  
  1605.         move.l    #"CWHD",(a0)+    ;write CWHD chunk name
  1606.  
  1607.         moveq    #14,d0
  1608.         move.l    d0,(a0)+        ;chunk size
  1609.  
  1610.         move.w    grid_across(a6),(a0)+
  1611.         move.w    grid_down(a6),(a0)+
  1612.         move.w    grid_firstx(a6),(a0)+
  1613.         move.w    grid_firsty(a6),(a0)+
  1614.         move.l    clue_list(a6),a1
  1615.         move.w    clh_AcCount(a1),(a0)+
  1616.         move.w    clh_DnCount(a1),(a0)+
  1617.         moveq    #0,d0
  1618.         btst    #6,applic_flag1(a6)    ;check cw type
  1619.  
  1620.         sne    d0
  1621.         neg.b    d0
  1622.         move.w    d0,(a0)+
  1623.  
  1624.         move.l    file_acs(a6),d0        ;got an ACCL chunk?
  1625.         beq.s    Save_F12            ;skip if not
  1626.  
  1627.         move.l    #"ACCL",(a0)+        ;create ACCL chunk
  1628.         move.l    d0,(a0)+            ;save size
  1629.  
  1630.         move.l    clue_list(a6),a1
  1631.         move.w    clh_AcCount(a1),d1    ;no. to do
  1632.         move.l    clh_AcList(a1),a1        ;ptr to list
  1633.  
  1634. Save_F13        move.w    cle_Num(a1),(a0)+        ;pop in clue num.
  1635.         move.w    cle_AcSq(a1),(a0)+    ;across start square
  1636.         move.w    cle_DnSq(a1),(a0)+    ;down start square
  1637.         move.b    cle_Solved(a1),d0
  1638.         ext.w    d0
  1639.         move.w    d0,(a0)+            ;solved status
  1640.  
  1641.         move.l    cle_Text(a1),d2        ;ptr to text
  1642.         bne.s    Save_F13_1        ;skip if exists
  1643.  
  1644.         clr.w    (a0)+        ;else pop in NULLs
  1645.         bra.s    Save_F15        ;guaranteed aligned!
  1646.  
  1647. Save_F13_1    move.l    d2,a2        ;ptr to text itself
  1648.  
  1649. Save_F14        move.b    (a2)+,(a0)+        ;copy text across
  1650.         bne.s    Save_F14            ;and back until EOS
  1651.  
  1652.         move.l    a0,d0            ;check alignment
  1653.         btst    #0,d0            ;odd address?
  1654.         beq.s    Save_F15            ;skip if even
  1655.         clr.b    (a0)+            ;else make it even
  1656. Save_F15        add.w    #cle_sizeof,a1        ;point to next entry
  1657.         subq.w    #1,d1            ;done them all?
  1658.         bne.s    Save_F13
  1659.  
  1660.  
  1661. Save_F12        move.l    file_dns(a6),d0        ;got a DNCL chunk?
  1662.         beq.s    Save_F16            ;skip if not
  1663.  
  1664.         move.l    #"DNCL",(a0)+        ;create DNCL chunk
  1665.         move.l    d0,(a0)+            ;save size
  1666.  
  1667.         move.l    clue_list(a6),a1
  1668.         move.w    clh_DnCount(a1),d1    ;no. to do
  1669.         move.l    clh_DnList(a1),a1        ;ptr to list
  1670.  
  1671. Save_F17        move.w    cle_Num(a1),(a0)+        ;pop in clue num.
  1672.         move.w    cle_AcSq(a1),(a0)+    ;across start square
  1673.         move.w    cle_DnSq(a1),(a0)+    ;down start square
  1674.         move.b    cle_Solved(a1),d0
  1675.         ext.w    d0
  1676.         move.w    d0,(a0)+            ;solved status
  1677.  
  1678.         move.l    cle_Text(a1),d2        ;get text ptr
  1679.         bne.s    Save_F17_1        ;skip if exists
  1680.  
  1681.         clr.w    (a0)+        ;else pop in NULLs
  1682.         bra.s    Save_F19        ;guaranteed aligned!
  1683.  
  1684. Save_F17_1    move.l    d2,a2        ;ptr to text itself
  1685.  
  1686. Save_F18        move.b    (a2)+,(a0)+        ;copy text across
  1687.         bne.s    Save_F18            ;and back until EOS
  1688.  
  1689.         move.l    a0,d0            ;check alignment
  1690.         btst    #0,d0            ;odd address?
  1691.         beq.s    Save_F19            ;skip if even
  1692.         clr.b    (a0)+            ;else make it even
  1693. Save_F19        add.w    #cle_sizeof,a1        ;point to next entry
  1694.         subq.w    #1,d1            ;done them all?
  1695.         bne.s    Save_F17
  1696.  
  1697. Save_F16        move.l    #"GRID",(a0)+        ;create GRID chunk
  1698.  
  1699.         move.l    grid_bytes(a6),d0
  1700.         move.l    d0,(a0)+            ;& grid chunk size
  1701.  
  1702.         lsr.l    #1,d0
  1703.         move.l    grid_array(a6),a1
  1704.  
  1705. Save_F20        move.w    (a1)+,(a0)+        ;copy grid across
  1706.         subq.l    #1,d0            ;verbatim
  1707.         bne.s    Save_F20
  1708.  
  1709.  
  1710. * Now save the IFF file to disc.
  1711.  
  1712.  
  1713.         bsr    CheckFileName    ;got a valid file name?
  1714.         tst.b    file_flag2(a6)
  1715.         bmi.s    Save_F20a    ;skip if so
  1716.  
  1717.         moveq    #1,d0        ;else report 'invalid
  1718.         bra    Load_Error    ;file name' error
  1719.  
  1720. ;        bpl.s    Save_F22        ;skip if not
  1721.  
  1722. Save_F20a    lea    AcrossBuf(pc),a0
  1723.         move.l    a0,dir_name(a6)
  1724.         bsr    SetPath1
  1725.  
  1726.         move.l    dir_name(a6),a1
  1727.  
  1728. Save_F23        tst.b    (a1)+        ;skip to end of
  1729.         bne.s    Save_F23        ;path name
  1730.  
  1731.         lea    ND_FileName(pc),a0    ;get file name
  1732.         move.l    gg_SpecialInfo(a0),a0    ;from string
  1733.         move.l    si_Buffer(a0),a0        ;gadget
  1734.  
  1735.         subq.l    #1,a1        ;point to EOS
  1736.         cmp.b    #":",-1(a1)    ;volume separator?
  1737.         beq.s    Save_F23a    ;skip if so
  1738.         cmp.b    #"/",-1(a1)    ;directory separator?
  1739.         beq.s    Save_F23a    ;skip if so
  1740.         move.b    #"/",(a1)+    ;else put it in!
  1741.  
  1742. Save_F23a    bsr    CopyString    ;append to path name
  1743.  
  1744.         move.l    dir_name(a6),d1
  1745.         move.l    #MODE_NEW,d2
  1746.         CALLDOS    Open        ;try opening file
  1747.  
  1748.         move.l    d0,file_shand(a6)    ;got it?
  1749.         bne.s    Save_F23b    ;skip if so
  1750.  
  1751.         moveq    #6,d0        ;else report "can't
  1752.         bra    Load_Error    ;save file" error
  1753.  
  1754. ;        beq.s    Save_F22            ;skip if not
  1755.  
  1756. Save_F23b    move.l    d0,d1
  1757.         move.l    file_buffer(a6),d2    ;write out the
  1758.         move.l    file_size(a6),d3        ;file
  1759.         CALLDOS    Write
  1760.  
  1761.         move.l    file_shand(a6),d1        ;and close it
  1762.         CALLDOS    Close
  1763.  
  1764.  
  1765. * Now deallocate the memory used by the file buffer.
  1766.  
  1767.  
  1768. ;Save_F22    move.l    file_buffer(a6),d0    ;got a buffer?
  1769. ;        beq.s    Save_F22a        ;skip if not
  1770. ;        move.l    d0,a1
  1771. ;        move.l    file_size(a6),d0        ;get rid of it if so
  1772. ;        CALLEXEC    FreeMem
  1773.  
  1774.  
  1775. * Now display the new disc directory.
  1776.  
  1777.  
  1778. Save_F22a    moveq    #0,d0
  1779.         bra    Load_Error
  1780.  
  1781.  
  1782. ;        bra    ShowDir
  1783.  
  1784.  
  1785. * Come here if some operation failed.
  1786.  
  1787.  
  1788. Save_F11        rts
  1789.  
  1790.  
  1791. * LoadFile(a6)
  1792. * a6 = ptr to main program variables
  1793.  
  1794. * Loads crossword file. Kills off current crossword in
  1795. * grid, then reallocates all memory & begins setting up
  1796. * all of the data.
  1797.  
  1798. * ASSUME ALL REGISTERS CORRUPT
  1799.  
  1800.  
  1801. LoadFile        clr.l    file_buffer(a6)
  1802.         clr.b    wantdir(a6)    ;don't want dir listing!
  1803.  
  1804.         bsr    CheckFileName    ;got a valid file name?
  1805.         tst.b    file_flag2(a6)
  1806.         bmi.s    Load_X1        ;skip if so
  1807.  
  1808.         moveq    #1,d0        ;invalid filename
  1809.         bra    Load_Error    ;signal error
  1810.  
  1811. ;        bpl    Load_Error    ;skip if not
  1812.  
  1813. Load_X1        lea    AcrossBuf(pc),a0
  1814.         move.l    a0,dir_name(a6)
  1815.         bsr    SetPath1
  1816.  
  1817.         move.l    dir_name(a6),a1
  1818.  
  1819. Load_F1        tst.b    (a1)+        ;skip to end of
  1820.         bne.s    Load_F1        ;path name
  1821.  
  1822.         lea    ND_FileName(pc),a0    ;get file name
  1823.         move.l    gg_SpecialInfo(a0),a0    ;from string
  1824.         move.l    si_Buffer(a0),a0        ;gadget
  1825.  
  1826.         subq.l    #1,a1        ;point to EOS
  1827.         cmp.b    #":",-1(a1)    ;volume separator?
  1828.         beq.s    Load_F1a        ;skip if so
  1829.         cmp.b    #"/",-1(a1)    ;directory separator?
  1830.         beq.s    Load_F1a        ;skip if so
  1831.         move.b    #"/",(a1)+    ;else put it in!
  1832.  
  1833. Load_F1a        bsr    CopyString    ;append to path name
  1834.  
  1835.         move.l    dir_iblk(a6),d0    ;got a file info block?
  1836.         bne.s    Load_F2        ;skip if so
  1837.  
  1838.         move.l    #260,d0
  1839.         move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  1840.         CALLEXEC    AllocMem
  1841.  
  1842.         move.l    d0,dir_iblk(a6)    ;got one?
  1843.         bne.s    Load_F2
  1844.  
  1845.         moveq    #-1,d0        ;no memory on tap
  1846.         bra    Load_Error
  1847.  
  1848. ;        beq    Load_Error
  1849.  
  1850. Load_F2        move.l    dir_name(a6),d1
  1851.         move.l    #ACCESS_READ,d2
  1852.         CALLDOS    Lock        ;got a file lock?
  1853.         move.l    d0,dir_lock(a6)
  1854.         bne.s    Load_X2
  1855.  
  1856.         moveq    #2,d0        ;file nonexistent
  1857.         bra    Load_Error
  1858.  
  1859. ;        beq    Load_Error    ;no-file doesn't exist
  1860.  
  1861. Load_X2        move.l    d0,d1
  1862.         move.l    dir_iblk(a6),d2
  1863.         CALLDOS    Examine
  1864.  
  1865.         move.l    d0,-(sp)        ;save error code
  1866.         move.l    dir_lock(a6),d1
  1867.         clr.l    dir_lock(a6)
  1868.         CALLDOS    UnLock        ;surrender the lock
  1869.  
  1870.         tst.l    (sp)+        ;able to examine?
  1871.         bne.s    Load_X3        ;skip if so
  1872.  
  1873.         moveq    #2,d0        ;nonexistent file error
  1874.         bra    Load_Error
  1875.  
  1876. ;        beq    Load_Error    ;no-error
  1877.  
  1878. Load_X3        move.l    dir_iblk(a6),a0    ;get info block
  1879.         move.l    124(a0),d0    ;get file size
  1880.         bne.s    Load_X4        ;ok
  1881.  
  1882.         moveq    #3,d0        ;empty file error
  1883.         bra    Load_Error
  1884.  
  1885. ;        beq    Load_Error    ;cock up-empty file!
  1886.  
  1887. Load_X4        move.l    d0,file_size(a6)
  1888.  
  1889.         move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  1890.         CALLEXEC    AllocMem
  1891.         move.l    d0,file_buffer(a6)    ;got file buffer?
  1892.         bne.s    Load_X5
  1893.  
  1894.         moveq    #-1,d0
  1895.         bra    Load_Error
  1896.  
  1897. ;        beq    Load_Error        ;no
  1898.  
  1899. Load_X5        move.l    dir_name(a6),d1    ;try opening file
  1900.         move.l    #MODE_OLD,d2
  1901.         CALLDOS    Open
  1902.         move.l    d0,file_lhand(a6)    ;got it?
  1903.         bne.s    Load_X6
  1904.  
  1905.         moveq    #5,d0        ;can't open file
  1906.         bra    Load_Error
  1907.  
  1908. ;        beq    Load_Error    ;no
  1909.  
  1910. Load_X6        move.l    d0,d1
  1911.         move.l    file_buffer(a6),d2    ;get file
  1912.         move.l    file_size(a6),d3        ;contents
  1913.         CALLDOS    Read
  1914.  
  1915.         move.l    file_lhand(a6),d1        ;and close file
  1916.         CALLDOS    Close
  1917.  
  1918.  
  1919. * Now scan the IFF file for the various chunks, and set up the
  1920. * new data.
  1921.  
  1922.  
  1923.         move.l    file_buffer(a6),a0
  1924.         move.l    #"FORM",d0
  1925.         cmp.l    (a0)+,d0        ;IFF FORM?
  1926.         beq.s    Load_X12
  1927.  
  1928.         moveq    #4,d0
  1929.         bra    Load_Error    ;not an IFF File
  1930.  
  1931. Load_X12        move.l    (a0)+,d0
  1932.         addq.l    #8,d0
  1933.         cmp.l    file_size(a6),d0
  1934.         beq.s    Load_X13
  1935.  
  1936.         moveq    #4,d0
  1937.         bra    Load_Error    ;again not an IFF file
  1938.  
  1939. Load_X13        move.l    #"CRWD",d0
  1940.         cmp.l    (a0)+,d0
  1941.         beq.s    Load_X14
  1942.  
  1943.         moveq    #4,d0
  1944.         bra    Load_Error    ;not our IFF file
  1945.  
  1946. Load_X14        move.l    #"CWHD",d0        ;got a CWHD?
  1947.         move.l    file_buffer(a6),a0
  1948.         bsr    FindChunk
  1949.         move.l    d0,file_cwhd(a6)
  1950.         bne.s    Load_X7
  1951.  
  1952.         moveq    #7,d0        ;missing vital chunk
  1953.         bra    Load_Error
  1954.  
  1955. ;        beq    Load_Error        ;exit if not
  1956.  
  1957. Load_X7        move.l    #"GRID",d0        ;got a GRID?
  1958.         move.l    file_buffer(a6),a0
  1959.         bsr    FindChunk
  1960.         move.l    d0,file_grid(a6)
  1961.         bne.s    Load_X8
  1962.  
  1963.         moveq    #7,d0        ;missing vital chunk
  1964.         bra    Load_Error
  1965. ;        beq    Load_Error        ;exit if not
  1966.  
  1967. Load_X8        move.l    #"ACCL",d0        ;got an ACCL?
  1968.         move.l    file_buffer(a6),a0
  1969.         bsr    FindChunk        ;no error if not!
  1970.         move.l    d0,file_accl(a6)
  1971.  
  1972.         move.l    #"DNCL",d0        ;got a DNCL?
  1973.         move.l    file_buffer(a6),a0
  1974.         bsr    FindChunk
  1975.         move.l    d0,file_dncl(a6)
  1976.  
  1977.  
  1978. * Now destroy the old crossword. Also destroy old Undo Array
  1979. * (new for 1.2).
  1980.  
  1981.  
  1982.         move.l    grid_array(a6),a1
  1983.         move.l    grid_bytes(a6),d0
  1984.         CALLEXEC    FreeMem
  1985.  
  1986.         move.l    undo_array(a6),a1
  1987.         move.l    grid_bytes(a6),d0
  1988.         CALLEXEC    FreeMem
  1989.  
  1990.         bsr    FreeText
  1991.  
  1992.         bsr    DisposeClueList
  1993.  
  1994.  
  1995. * Now start creating the new crossword. First set up the base
  1996. * variables for the crossword.
  1997.  
  1998.  
  1999.         move.l    file_cwhd(a6),a0
  2000.         addq.l    #8,a0        ;point to CWHD vars
  2001.  
  2002.         move.w    (a0)+,grid_across(a6)
  2003.         move.w    (a0)+,grid_down(a6)
  2004.         move.w    (a0)+,grid_firstx(a6)
  2005.         move.w    (a0)+,grid_firsty(a6)
  2006.         move.w    4(a0),d0
  2007.         and.b    #1,d0
  2008.         ror.b    #2,d0            ;get type bit
  2009.         move.b    applic_flag1(a6),d1    ;and current flags
  2010.         and.b    #$BF,d1
  2011.         or.b    d0,d1
  2012.         move.b    d1,applic_flag1(a6)    ;set CW type
  2013.  
  2014.         move.l    file_grid(a6),a0
  2015.         addq.l    #4,a0        ;point to grid size
  2016.  
  2017.         move.l    (a0)+,d0
  2018.         move.l    d0,grid_bytes(a6)
  2019.  
  2020.         move.l    a0,-(sp)
  2021.         move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1    ;get new grid
  2022.         CALLEXEC    AllocMem
  2023.         move.l    (sp)+,a0
  2024.  
  2025.         move.l    d0,grid_array(a6)        ;got it?
  2026.         bne.s    Load_X9            ;continue if so
  2027.  
  2028.         moveq    #-1,d0        ;no memory
  2029.         bra    Load_Error    ;so report error
  2030.  
  2031.  
  2032. Load_X9        move.l    d0,a1        ;a1 points to grid_array
  2033.  
  2034.         movem.l    a0-a1,-(sp)    ;save pointers
  2035.         move.l    grid_bytes(a6),d0
  2036.         move.l    #MEMF_PUBLIC+MEMF_CHIP,d1    ;get undo array
  2037.         CALLEXEC    AllocMem
  2038.         movem.l    (sp)+,a0-a1        ;recover pointers
  2039.         move.l    d0,undo_array(a6)        ;got it?
  2040.         bne.s    Load_X10            ;continue if so
  2041.  
  2042.         moveq    #-1,d0        ;no memory
  2043.         bra    Load_Error    ;so report error
  2044.  
  2045. Load_X10        move.l    grid_bytes(a6),d0        ;size of grid
  2046.  
  2047. Load_F3        move.b    (a0)+,(a1)+        ;set up the grid
  2048.         subq.l    #1,d0            ;chars array
  2049.         bne.s    Load_F3
  2050.  
  2051.         bsr    InitUndo        ;initialise UNDO array
  2052.  
  2053.         bclr    #4,applic_flag1(a6) ;clear clue list exists flag
  2054.  
  2055.         move.l    file_accl(a6),d0    ;ACCL chunk exists?
  2056.         beq.s    Load_F4        ;no, so skip
  2057.  
  2058.         bset    #4,applic_flag1(a6) ;else set clue
  2059.                       ;list exists flag
  2060.  
  2061.         move.l    file_cwhd(a6),a1
  2062.         addq.l    #8,a1        ;point to CWHD vars
  2063.         move.w    8(a1),d0
  2064.         mulu    #cle_sizeof,d0
  2065.  
  2066.         move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  2067.         CALLEXEC    AllocMem
  2068.         move.l    clue_list(a6),a0        ;got memory for
  2069.         move.l    d0,clh_AcList(a0)        ;clue list?
  2070.         beq.s    Load_F4            ;skip if not
  2071.  
  2072.         move.l    file_cwhd(a6),a1
  2073.         addq.l    #8,a1        ;point to CWHD vars
  2074.         move.w    8(a1),d0
  2075.         move.w    d0,clh_AcCount(a0)
  2076.  
  2077.         move.l    file_accl(a6),a1
  2078.         addq.l    #8,a1        ;point to ACCL entries
  2079.  
  2080.         move.l    clh_AcList(a0),a0    ;point to list space
  2081.  
  2082. Load_F5        move.w    (a1)+,cle_Num(a0)        ;create clue list
  2083.         move.w    (a1)+,cle_AcSq(a0)    ;entry
  2084.         move.w    (a1)+,cle_DnSq(a0)
  2085.         move.w    (a1)+,d1
  2086.         move.b    d1,cle_Solved(a0)
  2087.         clr.l    cle_Text(a0)
  2088.  
  2089. Load_F9        tst.b    (a1)+        ;skip to end of text
  2090.         bne.s    Load_F9
  2091.         move.l    a1,d2
  2092.         btst    #0,d2
  2093.         beq.s    Load_F10
  2094.  
  2095.         addq.l    #1,a1
  2096.  
  2097. Load_F10        add.w    #cle_sizeof,a0
  2098.         subq.w    #1,d0
  2099.         bne.s    Load_F5
  2100.  
  2101.  
  2102. Load_F4        move.l    file_dncl(a6),d0    ;DNCL chunk exists?
  2103.         beq.s    Load_F7        ;no, so skip
  2104.  
  2105.         bset    #4,applic_flag1(a6) ;else set clue
  2106.                       ;list exists flag
  2107.  
  2108.         move.l    file_cwhd(a6),a1
  2109.         addq.l    #8,a1        ;point to CWHD vars
  2110.         move.w    10(a1),d0
  2111.         mulu    #cle_sizeof,d0
  2112.  
  2113.         move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  2114.         CALLEXEC    AllocMem
  2115.         move.l    clue_list(a6),a0        ;got memory for
  2116.         move.l    d0,clh_DnList(a0)        ;clue list?
  2117.         beq.s    Load_F7            ;skip if not
  2118.  
  2119.         move.l    file_cwhd(a6),a1
  2120.         addq.l    #8,a1        ;point to CWHD vars
  2121.         move.w    10(a1),d0
  2122.         move.w    d0,clh_DnCount(a0)
  2123.  
  2124.         move.l    file_dncl(a6),a1
  2125.         addq.l    #8,a1
  2126.         move.l    clh_DnList(a0),a0    ;point to list space
  2127.  
  2128. Load_F6        move.w    (a1)+,cle_Num(a0)        ;create clue list
  2129.         move.w    (a1)+,cle_AcSq(a0)    ;entry
  2130.         move.w    (a1)+,cle_DnSq(a0)
  2131.         move.w    (a1)+,d1
  2132.         move.b    d1,cle_Solved(a0)
  2133.         clr.l    cle_Text(a0)
  2134.  
  2135. Load_F11        tst.b    (a1)+        ;skip to end of text
  2136.         bne.s    Load_F11
  2137.         move.l    a1,d2
  2138.         btst    #0,d2
  2139.         beq.s    Load_F12
  2140.  
  2141.         addq.l    #1,a1
  2142.  
  2143. Load_F12        add.w    #cle_sizeof,a0
  2144.         subq.w    #1,d0
  2145.         bne.s    Load_F6
  2146.  
  2147. Load_F7        bsr    AllocText    ;create text space
  2148.         tst.w    d0        ;got it?
  2149.         beq    Load_F8        ;skip if not
  2150.  
  2151.  
  2152. * Now pop in the clue texts where they exist.
  2153.  
  2154.  
  2155.         move.l    clue_list(a6),a0
  2156.         move.l    clh_AcList(a0),d0    ;got across clue list?
  2157.         beq.s    Load_F17        ;oops..
  2158.  
  2159.         move.w    clh_AcCount(a0),d1    ;no. to do
  2160.         move.l    d0,a2            ;ptr to list
  2161.         move.l    file_accl(a6),a0        ;get ACCL chunk
  2162.         addq.l    #8,a0            ;point to entries
  2163.         move.l    clue_endptr(a6),a1
  2164.  
  2165. Load_F15        addq.l    #8,a0        ;point to text
  2166.         tst.w    (a0)        ;text exists?
  2167.         bne.s    Load_F15_1    ;yes, so pop it in
  2168.  
  2169.         addq.l    #2,a0        ;else skip
  2170.         bra.s    Load_F16        ;and do next entry
  2171.  
  2172. Load_F15_1    move.l    a1,cle_Text(a2)    ;pop in pointer
  2173.         bsr    CopyString
  2174.  
  2175.         move.l    a0,d0        ;check if we're
  2176.         btst    #0,d0        ;already aligned
  2177.         beq.s    Load_F16
  2178.         addq.l    #1,a0        ;and word align if not
  2179.  
  2180. Load_F16        add.w    #cle_sizeof,a2    ;next list entry
  2181.         subq.w    #1,d1        ;done them all?
  2182.         bne.s    Load_F15        ;back if so
  2183.  
  2184.         move.l    a1,clue_endptr(a6)
  2185.  
  2186. Load_F17        move.l    clue_list(a6),a0
  2187.         move.l    clh_DnList(a0),d0    ;got across clue list?
  2188.         beq.s    Load_F8        ;oops..
  2189.  
  2190.         move.w    clh_DnCount(a0),d1    ;no. to do
  2191.         move.l    d0,a2            ;ptr to list
  2192.         move.l    file_dncl(a6),a0        ;get DNCL chunk
  2193.         addq.l    #8,a0            ;point to entries
  2194.         move.l    clue_endptr(a6),a1
  2195.  
  2196. Load_F13        addq.l    #8,a0        ;point to text
  2197.         tst.w    (a0)        ;text exists?
  2198.         bne.s    Load_F13_1    ;skip if so
  2199.  
  2200.         addq.l    #2,a0        ;else skip
  2201.         bra.s    Load_F14        ;and do next entry
  2202.  
  2203. Load_F13_1    move.l    a1,cle_Text(a2)    ;pop in pointer
  2204.         bsr    CopyString
  2205.  
  2206.         move.l    a0,d0        ;check if we're
  2207.         btst    #0,d0        ;already aligned
  2208.         beq.s    Load_F14
  2209.         addq.l    #1,a0        ;and word align if not
  2210.  
  2211. Load_F14        add.w    #cle_sizeof,a2    ;next list entry
  2212.         subq.w    #1,d1        ;done them all?
  2213.         bne.s    Load_F13        ;back if so
  2214.  
  2215.         move.l    a1,clue_endptr(a6)
  2216.  
  2217.  
  2218. * Now begin re-displaying the grid.
  2219.  
  2220.  
  2221. Load_F8        move.w    #GRID_LEFT,d0    ;set new mouse grid
  2222.         move.w    d0,grid_hl(a6)    ;limits!
  2223.         move.w    #SQ_X,d1
  2224.         move.w    grid_across(a6),d2
  2225.         cmp.w    #MAX_DISPX,d2
  2226.         bls.s    Load_F8a
  2227.         move.w    #MAX_DISPX,d2    ;constrain oversize grid
  2228. Load_F8a        mulu    d2,d1
  2229.         add.w    d1,d0
  2230.         subq.w    #1,d0
  2231.         move.w    d0,grid_hu(a6)
  2232.  
  2233.         move.w    #GRID_UP,d0
  2234.         move.w    d0,grid_vl(a6)
  2235.         move.w    #SQ_Y,d1
  2236.         move.w    grid_down(a6),d2
  2237.         cmp.w    #MAX_DISPY,d2
  2238.         bls.s    Load_F8b
  2239.         move.w    #MAX_DISPY,d2    ;constrain oversize grid
  2240. Load_F8b        mulu    d2,d1
  2241.         add.w    d1,d0
  2242.         subq.w    #1,d0
  2243.         move.w    d0,grid_vu(a6)
  2244.  
  2245.         move.l    mw_handle(a6),a0        ;turn on the "Fill
  2246.         move.w    #1+0*32+0*2048+$F800,d0    ;Black" menu item
  2247.         CALLINT    OnMenu
  2248.  
  2249.         btst    #6,applic_flag1(a6)    ;Type 2 grid?
  2250.         beq.s    Load_F8c            ;skip if not
  2251.  
  2252.         move.l    mw_handle(a6),a0        ;turn off the "Fill
  2253.         move.w    #1+0*32+0*2048+$F800,d0    ;Black" menu item
  2254.         CALLINT    OffMenu
  2255.  
  2256. Load_F8c        move.l    mw_rastport(a6),a1    ;tmp change
  2257.         moveq    #0,d0            ;plotting pen
  2258.         CALLGRAF    SetAPen
  2259.  
  2260.         move.l    mw_rastport(a6),a1    ;erase image
  2261.         move.w    #GRID_LEFT,d0        ;from screen
  2262.         move.w    #GRID_UP,d1
  2263.         move.w    #GRID_LEFT+MAX_DISP_PX,d2
  2264.         move.w    #GRID_UP+MAX_DISP_PY,d3
  2265.         CALLGRAF    RectFill
  2266.  
  2267.         move.l    mw_rastport(a6),a1    ;recover original
  2268.         moveq    #4,d0            ;detail pen
  2269.         CALLGRAF    SetAPen
  2270.  
  2271.         move.l    grid_rp(a6),a1
  2272.         moveq    #1,d0
  2273.         CALLGRAF    SetRast        ;get rid of old grid image
  2274.  
  2275.         bsr    SetMainHVPots    ;set PropGadgets & TLC
  2276.  
  2277.         move.l    grid_array(a6),a0
  2278.  
  2279.         move.w    grid_down(a6),d6    ;outer loop counter
  2280.  
  2281.         moveq    #1,d1        ;vertical start square
  2282.         bra.s    Load_A1
  2283.  
  2284. Load_L1        move.w    grid_across(a6),d7    ;inner loop counter
  2285.  
  2286.         moveq    #1,d0        ;horizontal start square
  2287.  
  2288.         bra.s    Load_A2
  2289.  
  2290. Load_L2        move.w    (a0)+,d2            ;get square data
  2291.         movem.l    d0-d1/d6-d7/a0,-(sp)    ;save this lot
  2292.         bsr    SetSquare        ;change grid image
  2293.         movem.l    (sp)+,d0-d1/d6-d7/a0    ;recover this lot
  2294.         addq.w    #1,d0            ;next horiz. square
  2295.  
  2296. Load_A2        dbra    d7,Load_L2        ;do this many
  2297.         addq.w    #1,d1            ;next vert. square
  2298.  
  2299. Load_A1        dbra    d6,Load_L1        ;do this many
  2300.  
  2301.         bsr    DisplayGrid        ;show results!
  2302.  
  2303.         bsr    InitUndo        ;initialise Undo array
  2304.  
  2305.         moveq    #0,d0        ;signal no error
  2306.  
  2307. Load_Error    move.w    d0,disc_error(a6)
  2308.         beq.s    Load_Done
  2309.  
  2310.         lea    IRT_1(pc),a0
  2311.         lea    _DiscErrs(pc),a1
  2312.         add.w    d0,d0
  2313.         add.w    d0,d0
  2314.         add.w    d0,d0
  2315.         add.w    d0,a1
  2316.         move.l    (a1)+,d0
  2317.         beq.s    Load_Done
  2318.         move.l    (a1)+,d1
  2319.         move.l    a0,irt_itext(a6)
  2320.         move.l    d0,irt_tlist(a6)
  2321.         move.w    d1,irt_count(a6)
  2322.  
  2323.         bsr    ShowDiscInfo
  2324.  
  2325.  
  2326. * Don't forget to free up any file transfer buffers used!
  2327.  
  2328.  
  2329. Load_Done    move.l    file_buffer(a6),d0    ;got a buffer?
  2330.         beq.s    Load_Bye            ;skip if not
  2331.         move.l    d0,a1
  2332.         move.l    file_size(a6),d0        ;get rid of it if so
  2333.         CALLEXEC    FreeMem
  2334.         clr.l    file_buffer(a6)    ;and make sure it's gone!
  2335.  
  2336. Load_Bye        tst.b    wantdir(a6)    ;want a fresh dir listing?
  2337.  
  2338.         bne    ShowDir        ;skip if so
  2339.  
  2340.         rts
  2341.  
  2342.  
  2343.         dc.l    NoMemOnTap,5    ;-1, No memory
  2344.  
  2345. _DiscErrs    dc.l    0,0        ;0, OK
  2346.         dc.l    NoNameBozo,4    ;1, No filename in box
  2347.         dc.l    NoFileBozo,4    ;2, File doesn't exist
  2348.         dc.l    FileEmpty,4    ;3, Empty file
  2349.         dc.l    NotIFF,4        ;4, Not IFF File
  2350.         dc.l    CantLoad,4    ;5, Can't Load file
  2351.         dc.l    CantSave,4    ;6, Can't Save File
  2352.         dc.l    NoChunkBozo,4    ;7, Missing vital IFF Chunk
  2353.         dc.l    WProtect,6    ;8, Disc Write Protected
  2354.         dc.l    CantRename,5    ;9, Can't Rename
  2355.         dc.l    CantDelete,3    ;10, Can't Delete
  2356.         dc.l    DirExists,6    ;11, file/dir already exists
  2357.         dc.l    NonEmptyDir,5    ;12, nonempty directory
  2358.         dc.l    NoPort,4        ;13, no port for format
  2359.         dc.l    NoIOReq,4    ;14, no IOReq for format
  2360.         dc.l    NoDev,4        ;15, can't open trackdisk
  2361.  
  2362.  
  2363. * UserRename(a6)
  2364. * a6 = ptr to main program variables
  2365.  
  2366. * Prompts for a new name to choose in the Rename gadget,
  2367. * then renames file.
  2368.  
  2369. * Assume ALL registers corrupt
  2370.  
  2371.  
  2372. UserRename    st    wantdir(a6)
  2373.  
  2374.         bsr    CheckFileName    ;got a valid file name?
  2375.         tst.b    file_flag2(a6)
  2376.         bmi.s    URN_1        ;skip if so
  2377.  
  2378.         moveq    #1,d0        ;invalid filename
  2379.         bra    Load_Error    ;signal error
  2380.  
  2381. URN_1        bsr    CheckReName    ;got a valid new name?
  2382.         btst    #6,file_flag2(a6)
  2383.         bne.s    URN_2        ;skip if so
  2384.  
  2385.         lea    IRT_1(pc),a0
  2386.         lea    IR_Rename(pc),a1
  2387.         moveq    #5,d0
  2388.  
  2389.         move.l    a0,irt_itext(a6)    ;else pop up InfoReq
  2390.         move.l    a1,irt_tlist(a6)    ;telling user to provide
  2391.         move.w    d0,irt_count(a6)    ;a new name
  2392.  
  2393.         bsr    ShowDiscInfo
  2394.  
  2395.         bra.s    URN_1
  2396.  
  2397. URN_2        lea    AcrossBuf(pc),a0
  2398.         move.l    a0,dir_name(a6)
  2399.         bsr    SetPath1
  2400.  
  2401.         move.l    dir_name(a6),a1
  2402.  
  2403. URN_3        tst.b    (a1)+        ;skip to end of
  2404.         bne.s    URN_3        ;path name
  2405.  
  2406.         lea    ND_FileName(pc),a0    ;get file name
  2407.         move.l    gg_SpecialInfo(a0),a0    ;from string
  2408.         move.l    si_Buffer(a0),a0        ;gadget
  2409.  
  2410.         subq.l    #1,a1        ;point to EOS
  2411.         cmp.b    #":",-1(a1)    ;volume separator?
  2412.         beq.s    URN_4        ;skip if so
  2413.         cmp.b    #"/",-1(a1)    ;directory separator?
  2414.         beq.s    URN_4        ;skip if so
  2415.         move.b    #"/",(a1)+    ;else put it in!
  2416.  
  2417. URN_4        bsr    CopyString    ;append to path name
  2418.  
  2419.         move.l    a1,dir_rename(a6)
  2420.         bsr    SetPath2
  2421.  
  2422.         move.l    dir_rename(a6),a1
  2423.  
  2424. URN_5        tst.b    (a1)+        ;skip to end of
  2425.         bne.s    URN_5        ;path name
  2426.  
  2427.         lea    ND_NewName(pc),a0        ;get new name
  2428.         move.l    gg_SpecialInfo(a0),a0    ;from string
  2429.         move.l    si_Buffer(a0),a0        ;gadget
  2430.  
  2431.         subq.l    #1,a1        ;point to EOS
  2432.         cmp.b    #":",-1(a1)    ;volume separator?
  2433.         beq.s    URN_6        ;skip if so
  2434.         cmp.b    #"/",-1(a1)    ;directory separator?
  2435.         beq.s    URN_6        ;skip if so
  2436.         move.b    #"/",(a1)+    ;else put it in!
  2437.  
  2438. URN_6        bsr    CopyString    ;append to path name
  2439.  
  2440.         move.l    dir_rename(a6),d1
  2441.         move.l    #ACCESS_READ,d2
  2442.         CALLDOS    Lock        ;got a file lock?
  2443.         tst.l    d0        ;if so, can't rename!
  2444.         beq.s    URN_7        ;skip if not (rename OK)
  2445.  
  2446.         move.l    d0,d1        ;else surrender lock
  2447.         CALLDOS    UnLock
  2448.  
  2449.         moveq    #9,d0        ;signal error
  2450.         bra    Load_Error    ;can't rename-file exists
  2451.  
  2452. URN_7        move.l    dir_name(a6),d1
  2453.         move.l    dir_rename(a6),d2
  2454.  
  2455.         CALLDOS    Rename        ;and rename file!
  2456.  
  2457.         moveq    #0,d0
  2458.         bra    Load_Error
  2459.  
  2460. ;        bra    ShowDir
  2461.  
  2462.         rts
  2463.  
  2464.  
  2465. * UserDelete(a6)
  2466. * a6 = ptr to main program variables
  2467.  
  2468. * Prompts if delete required, then executes delete
  2469. * if the delete is confirmed. Then resets the dir
  2470. * listing in the window & redisplays.
  2471.  
  2472. * Assume ALL registers corrupt
  2473.  
  2474.  
  2475. UserDelete    st    wantdir(a6)
  2476.  
  2477.         bsr    CheckFileName    ;got a valid file name?
  2478.         tst.b    file_flag2(a6)
  2479.         bmi.s    UDL_1        ;skip if so
  2480.  
  2481.         moveq    #1,d0        ;invalid filename
  2482.         bra    Load_Error    ;signal error
  2483.  
  2484. UDL_1        lea    QR_Delete(pc),a0    ;pop up the warning
  2485.         lea    QRT_1(pc),a1    ;requester!
  2486.         moveq    #5,d0
  2487.  
  2488.         move.l    a0,irt_tlist(a6)
  2489.         move.l    a1,irt_itext(a6)
  2490.         move.w    d0,irt_count(a6)
  2491.  
  2492. ;        bset    #6,applic_flag2(a6)    ;force NO gadget
  2493.  
  2494.         bsr    DoDiscQuery        ;pop up req
  2495.  
  2496.         btst    #6,applic_flag2(a6)    ;YES gadget hit?
  2497.         bne.s    UDL_2            ;skip if so
  2498.  
  2499.         rts                else do nothing
  2500.  
  2501. UDL_2        lea    AcrossBuf(pc),a0
  2502.         move.l    a0,dir_name(a6)
  2503.         bsr    SetPath1
  2504.  
  2505.         move.l    dir_name(a6),a1
  2506.  
  2507. UDL_3        tst.b    (a1)+        ;skip to end of
  2508.         bne.s    UDL_3        ;path name
  2509.  
  2510.         lea    ND_FileName(pc),a0    ;get file name
  2511.         move.l    gg_SpecialInfo(a0),a0    ;from string
  2512.         move.l    si_Buffer(a0),a0        ;gadget
  2513.  
  2514.         subq.l    #1,a1        ;point to EOS
  2515.         cmp.b    #":",-1(a1)    ;volume separator?
  2516.         beq.s    UDL_4        ;skip if so
  2517.         cmp.b    #"/",-1(a1)    ;directory separator?
  2518.         beq.s    UDL_4        ;skip if so
  2519.         move.b    #"/",(a1)+    ;else put it in!
  2520.  
  2521. UDL_4        bsr    CopyString    ;append to path name
  2522.  
  2523.         move.l    dir_name(a6),d1    ;check if file
  2524.         move.l    #ACCESS_READ,d2    ;actually exists
  2525.  
  2526.         CALLDOS    Lock
  2527.  
  2528.         move.l    d0,d7        ;file exists?
  2529.         bne.s    UDL_5        ;skip if so
  2530.  
  2531.         moveq    #2,d0        ;else report error
  2532.         bra    Load_Error
  2533.  
  2534. UDL_5        tst.l    dir_iblk(a6)    ;got a FileInfoBlock?
  2535.         bne.s    UDL_5a        ;use it if so
  2536.  
  2537.         move.l    #260,d0
  2538.         move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  2539.         CALLEXEC    AllocMem
  2540.         move.l    d0,dir_iblk(a6)    ;else allocate one
  2541.         bne.s    UDL_5a        ;and skip if got one
  2542.  
  2543.         moveq    #-1,d0        ;no memory-ERROR
  2544.         bra    Load_Error
  2545.  
  2546. UDL_5a        move.l    d7,d1
  2547.         move.l    dir_iblk(a6),d2
  2548.         CALLDOS    Examine        ;get file/dir info
  2549.  
  2550.         move.l    dir_iblk(a6),a0
  2551.         tst.l    4(a0)        ;file or dir?
  2552.         bmi.s    UDL_5b        ;skip if it's a file
  2553.  
  2554.         move.l    d7,d1
  2555.         move.l    a0,d2
  2556.         CALLDOS    ExNext        ;see if dir empty
  2557.         beq.s    UDL_5b        ;it is, so skip
  2558.  
  2559.         move.l    d7,d1        ;surrender the lock
  2560.         CALLDOS    UnLock
  2561.  
  2562.         moveq    #12,d0        ;non-empty directory-
  2563.         bra    Load_Error    ;can't erase.
  2564.  
  2565. UDL_5b        move.l    d7,d1        ;surrender the lock
  2566.         CALLDOS    UnLock
  2567.  
  2568.         move.l    dir_name(a6),d1
  2569.  
  2570.         CALLDOS    DeleteFile    ;and delete file!
  2571.  
  2572.         moveq    #0,d0
  2573.         bra    Load_Error
  2574.  
  2575. ;        bsr    ShowDir
  2576.  
  2577.         rts
  2578.  
  2579.  
  2580. * UserMakeDir(a6)
  2581. * a6 = ptr to main program variables
  2582.  
  2583. * Create new directory on disc, then re-create the
  2584. * dir listing & redisplay it.
  2585.  
  2586. * Assume ALL registers corrupt
  2587.  
  2588.  
  2589. UserMakeDir    st    wantdir(a6)
  2590.  
  2591.         bsr    CheckFileName    ;got a valid file name?
  2592.         tst.b    file_flag2(a6)
  2593.         bmi.s    UMD_1        ;skip if so
  2594.  
  2595.         moveq    #1,d0        ;invalid filename
  2596.         bra    Load_Error    ;signal error
  2597.  
  2598. UMD_1        lea    AcrossBuf(pc),a0
  2599.         move.l    a0,dir_name(a6)
  2600.         bsr    SetPath1
  2601.  
  2602.         move.l    dir_name(a6),a1
  2603.  
  2604. UMD_3        tst.b    (a1)+        ;skip to end of
  2605.         bne.s    UMD_3        ;path name
  2606.  
  2607.         lea    ND_FileName(pc),a0    ;get file name
  2608.         move.l    gg_SpecialInfo(a0),a0    ;from string
  2609.         move.l    si_Buffer(a0),a0        ;gadget
  2610.  
  2611.         subq.l    #1,a1        ;point to EOS
  2612.         cmp.b    #":",-1(a1)    ;volume separator?
  2613.         beq.s    UMD_4        ;skip if so
  2614.         cmp.b    #"/",-1(a1)    ;directory separator?
  2615.         beq.s    UMD_4        ;skip if so
  2616.         move.b    #"/",(a1)+    ;else put it in!
  2617.  
  2618. UMD_4        bsr    CopyString    ;append to path name
  2619.  
  2620.         move.l    dir_name(a6),d1    ;check if file
  2621.         move.l    #ACCESS_READ,d2    ;actually exists
  2622.  
  2623.         CALLDOS    Lock
  2624.  
  2625.         tst.l    d0        ;file exists?
  2626.         beq.s    UMD_5        ;skip if not
  2627.  
  2628.         move.l    d0,d1        ;surrender the lock
  2629.         CALLDOS    UnLock        ;if so
  2630.  
  2631.         moveq    #11,d0        ;and report error
  2632.         bra    Load_Error
  2633.  
  2634. UMD_5        move.l    dir_name(a6),d1
  2635.  
  2636.         CALLDOS    CreateDir    ;make new dir
  2637.  
  2638.         move.l    d0,d1        ;and surrender the lock
  2639.         CALLDOS    UnLock        ;without further ado!
  2640.  
  2641.         moveq    #0,d0
  2642.         bra    Load_Error
  2643.  
  2644. ;        bsr    ShowDir
  2645.  
  2646.         rts
  2647.  
  2648.  
  2649. * CopyFileName(a6)
  2650. * a6 = ptr to main program variables
  2651.  
  2652. * copy filename to rename box for editing.
  2653.  
  2654. * d0-d1/a0-a2 corrupt
  2655.  
  2656.  
  2657. CopyFileName    lea    ND_FileName(pc),a1    ;point to box gadgets
  2658.         move.l    a1,-(sp)            ;save ptr to them
  2659.  
  2660.         move.l    dp_window1(a6),a0        ;unlink gadgets
  2661.         moveq    #2,d0
  2662.         CALLINT    RemoveGList
  2663.  
  2664.         move.l    (sp),a1            ;point to FNameGad
  2665.         move.l    gg_NextGadget(a1),a0    ;point to RNameGad
  2666.         move.l    gg_SpecialInfo(a1),a1
  2667.         move.l    si_Buffer(a1),a1
  2668.         move.l    gg_SpecialInfo(a0),a0
  2669.         move.l    si_Buffer(a0),a0
  2670.  
  2671. CFN_1        move.b    (a1)+,(a0)+        ;copy chars
  2672.         bne.s    CFN_1            ;until EOS hit
  2673.  
  2674.         move.l    (sp),a1            ;pointer
  2675.         move.l    dp_window1(a6),a0
  2676.         sub.l    a2,a2
  2677.         moveq    #16,d0            ;16th starting at 0!
  2678.         moveq    #2,d1            ;2 gadgets
  2679.         CALLINT    AddGList            ;link back in
  2680.  
  2681.         move.l    (sp)+,a0
  2682.         move.l    dp_window1(a6),a1
  2683.         sub.l    a2,a2
  2684.         moveq    #2,d0
  2685.         CALLINT    RefreshGList        ;refresh them
  2686.  
  2687.         rts
  2688.  
  2689.  
  2690. * UserFormat(a6)
  2691. * a6 = ptr to main program variables
  2692.  
  2693. * Allows user to format a disc.
  2694. * Prompts for confirmation before doing so.
  2695.  
  2696. * Assume ALL registers corrupt!
  2697.  
  2698.  
  2699. UserFormat    clr.b    wantdir(a6)
  2700.  
  2701.         lea    QR_Format(pc),a0    ;pop up the warning
  2702.         lea    QRT_1(pc),a1    ;requester!
  2703.         moveq    #5,d0
  2704.  
  2705.         move.l    a0,irt_tlist(a6)
  2706.         move.l    a1,irt_itext(a6)
  2707.         move.w    d0,irt_count(a6)
  2708.  
  2709.         bsr    DoDiscQuery        ;pop up req
  2710.  
  2711.         btst    #6,applic_flag2(a6)    ;YES gadget hit?
  2712.         bne.s    UFT_2            ;skip if so
  2713.  
  2714.         rts                else do nothing
  2715.  
  2716. UFT_2        lea    IRT_1(pc),a0
  2717.         lea    HowToFormat(pc),a1    ;pop up the
  2718.         moveq    #5,d0            ;instructions!
  2719.  
  2720.         move.l    a0,irt_itext(a6)
  2721.         move.l    a1,irt_tlist(a6)
  2722.         move.w    d0,irt_count(a6)
  2723.  
  2724.         bsr    ShowDiscInfo
  2725.  
  2726.         bra    DoFormat
  2727.  
  2728.  
  2729. * FindChunk(a0,d0) -> d0
  2730. * a0 = ptr to IFF FORM
  2731. * d0 = 4-letter chunk name
  2732.  
  2733. * Returns ptr to chunk in D0 or zero if
  2734. * not found.
  2735.  
  2736. * d1-d2/a0-a1 corrupt
  2737.  
  2738.  
  2739. FindChunk    move.l    4(a0),d1        ;get file size
  2740.         move.l    a0,a1
  2741.         add.l    d1,a1        ;ptr to end of FORM
  2742.  
  2743.         lea    12(a0),a0    ;point to 1st chunk
  2744.  
  2745. FChunk_1        move.l    a0,d2        ;copy current ptr
  2746.         cmp.l    (a0)+,d0        ;got chunk?
  2747.         beq.s    FChunk_2        ;yes, so return
  2748.  
  2749.         add.l    (a0)+,a0        ;else point to next chunk
  2750. ;        addq.l    #4,a0
  2751.         cmp.l    a1,a0        ;hit end of FORM?
  2752.         bcs.s    FChunk_1        ;back if not
  2753.  
  2754.         moveq    #0,d2        ;else not found
  2755.  
  2756. FChunk_2        move.l    d2,d0
  2757.  
  2758.         rts
  2759.  
  2760.  
  2761. * WhichDrives(a6)
  2762. * a6 = ptr to main program variables
  2763. * Scans DOS device lists to find out which
  2764. * drives are attached to the system.
  2765.  
  2766. * Will also condition the Gadget Enable flags for the
  2767. * requisite gadgets.
  2768.  
  2769. * d0-d1/d7/a0-a1/a3 corrupt
  2770.  
  2771.  
  2772. WhichDrives    moveq    #0,d0
  2773.         move.l    d0,drv0(a6)    ;clear flags
  2774.  
  2775.         move.l    dos_base(a6),a3    ;ptr to DOS library
  2776.         move.l    34(a3),a3    ;pointer to RootNode
  2777.  
  2778.         move.l    24(a3),d1    ;get BPTR to DosInfo
  2779.         lsl.l    #2,d1
  2780.         move.l    d1,a3        ;get actual ptr
  2781.  
  2782.         move.l    4(a3),d1        ;get BPTR to DevInfo
  2783.         lsl.l    #2,d1
  2784.         move.l    d1,a3        ;get actual ptr
  2785.  
  2786. WDR_1        move.l    4(a3),d1        ;get DOS node type
  2787.         bne.s    WDR_5        ;not a device-skip
  2788.         move.l    40(a3),d7    ;get BPTR to name
  2789.         lsl.l    #2,d7
  2790.         addq.l    #1,d7
  2791.  
  2792.         move.l    d7,a0        ;actual ptr to string
  2793.         lea    _N_DRV1(pc),a1    ;check for DF0:
  2794.         bsr    CmpStr        ;this one?
  2795.         bne.s    WDR_2        ;no
  2796.  
  2797.         tst.l    8(a3)        ;task assigned to device node?
  2798.         beq.s    WDR_2        ;no
  2799.  
  2800.         st    drv0(a6)        ;else drive exists
  2801.         bra.s    WDR_5
  2802.  
  2803. WDR_2        move.l    d7,a0        ;actual ptr to string
  2804.         lea    _N_DRV2(pc),a1    ;check for DF1:
  2805.         bsr    CmpStr        ;this one?
  2806.         bne.s    WDR_3        ;no
  2807.  
  2808.         tst.l    8(a3)        ;task assigned to device node?
  2809.         beq.s    WDR_3        ;no
  2810.  
  2811.         st    drv1(a6)        ;else drive exists
  2812.         bra.s    WDR_5
  2813.  
  2814. WDR_3        move.l    d7,a0        ;actual ptr to string
  2815.         lea    _N_DRV3(pc),a1    ;check for RAM:
  2816.         bsr    CmpStr        ;this one?
  2817.         bne.s    WDR_4        ;no
  2818.  
  2819.         tst.l    8(a3)        ;task assigned to device node?
  2820.         beq.s    WDR_4        ;no
  2821.  
  2822.         st    drv2(a6)        ;else drive exists
  2823.         bra.s    WDR_5
  2824.  
  2825. WDR_4        move.l    d7,a0        ;actual ptr to string
  2826.         lea    _N_DRV4(pc),a1    ;check for DH:
  2827.         bsr    CmpStr        ;this one?
  2828.         bne.s    WDR_5        ;no
  2829.  
  2830.         tst.l    8(a3)        ;task assigned to device node?
  2831.         beq.s    WDR_5        ;no
  2832.  
  2833.         st    drv3(a6)        ;else drive exists
  2834.  
  2835. WDR_5        move.l    (a3),d1        ;get BPTR to next Device node
  2836.         beq.s    WDR_6        ;no more-skip
  2837.         lsl.l    #2,d1        ;else make true ptr
  2838.         move.l    d1,a3
  2839.         bra.s    WDR_1        ;and back for more
  2840.  
  2841. * Having established which drives are available,
  2842. * disable the gadgets linked to nonexistent drives.
  2843.  
  2844. WDR_6        lea    ND_PickDF0(pc),a0
  2845.         move.w    gg_Flags(a0),d0
  2846.         tst.b    drv0(a6)        ;DF0: available?
  2847.         bne.s    WDR_7        ;yes
  2848.         or.w    #GADGDISABLED,d0    ;else disable gadget
  2849.         move.w    d0,gg_Flags(a0)
  2850.  
  2851. WDR_7        lea    ND_PickDF1(pc),a0
  2852.         move.w    gg_Flags(a0),d0
  2853.         tst.b    drv1(a6)        ;DF1: available?
  2854.         bne.s    WDR_8        ;yes
  2855.         or.w    #GADGDISABLED,d0    ;else disable gadget
  2856.         move.w    d0,gg_Flags(a0)
  2857.  
  2858. WDR_8        lea    ND_PickRAM(pc),a0
  2859.         move.w    gg_Flags(a0),d0
  2860.         tst.b    drv2(a6)        ;RAM: available?
  2861.         bne.s    WDR_9        ;yes
  2862.         or.w    #GADGDISABLED,d0    ;else disable gadget
  2863.         move.w    d0,gg_Flags(a0)
  2864.  
  2865. WDR_9        lea    ND_PickDH(pc),a0
  2866.         move.w    gg_Flags(a0),d0
  2867.         tst.b    drv3(a6)        ;DH: available?
  2868.         bne.s    WDR_7        ;yes
  2869.         or.w    #GADGDISABLED,d0    ;else disable gadget
  2870.         move.w    d0,gg_Flags(a0)
  2871.  
  2872. WDR_10        rts
  2873.  
  2874.  
  2875. _N_DRV1        dc.b    "DF0",0
  2876.  
  2877. _N_DRV2        dc.b    "DF1",0
  2878.  
  2879. _N_DRV3        dc.b    "RAM",0
  2880.  
  2881. _N_DRV4        dc.b    "DH",0
  2882.  
  2883.         even
  2884.  
  2885.  
  2886.  
  2887.  
  2888.  
  2889.